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

Introduce initial ZSA support in Zebra (draft PR for CI checks) #8872

Closed

Conversation

dmidem
Copy link

@dmidem dmidem commented Sep 18, 2024

This draft PR introduces initial support for Zcash Shielded Assets (ZSA) in the Zebra codebase. The primary goal of this PR is to run CI checks provided by the ZcashFoundation repository to verify compilation correctness and execute unit and integration tests.

dmidem added 27 commits July 29, 2024 10:13
…l Orchard support only, without supporting and enabling ZSA features.
This commit introduces basic support for Transaction version 6 (Tx V6). This initial implementation treats Tx V6
as a simple copy of Tx V5, without yet integrating ZSA-specific features or the new transaction structure.

- Added a new V6 variant to the Transaction enum in the zebra-chain crate.
- Updated relevant code to handle the new V6 variant.

Note: Tests and additional adjustments are still pending, and will be addressed in subsequent commits.
…(without unit tests fixing for now).

- Refactored `ShieldedData` and `Action` structures to be generics parameterized by Orchard flavor
  (`OrchardVanilla` or `OrchardZSA`), enabling support for both Orchard protocols in Tx V6.
- Introduced a `burn` field in `ShieldedData` to support ZSA, with unit type for Tx V5 and a vector of burn items for Tx V6.
- Modified `Transaction` enum methods (orchard_...) to handle generics properly, ensuring compatibility with both Orchard flavors.
- Implemented serialization and deserialization for Tx V6 while avoiding code redundancy with Tx V5 wherever possible.
@github-actions github-actions bot added the C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG label Sep 18, 2024
@gustavovalverde gustavovalverde added A-rust Area: Updates to Rust code labels Sep 18, 2024
@dmidem dmidem marked this pull request as ready for review September 23, 2024 09:42
@dmidem dmidem requested review from a team as code owners September 23, 2024 09:42
@dmidem dmidem requested review from arya2 and upbqdn and removed request for a team September 23, 2024 09:42
@arya2
Copy link
Contributor

arya2 commented Sep 24, 2024

It's not possible to fix all of the complaints from cargo-deny until the changes in librustzcash have been published, and not urgent to fix any of them, but see Continuous Integration in the Zebra book for how to fix duplicate dependencies in the deny.toml checks for later.

Note: at least the windows-sys entry should be updated when updating Zebra's dependencies on main.

Building zebra-chain without any default features seems to be the only failure that needs fixing:
https://github.com/ZcashFoundation/zebra/actions/runs/11015467979/job/30589574007?pr=8872

@gustavovalverde Is there anything else we could try to get this one working?

@mpguerra
Copy link
Contributor

I think probably it's good enough to see where it's failing now and see if there are any actionable failures on the QEDIT side, e.g maybe https://github.com/ZcashFoundation/zebra/actions/runs/11015467979/job/30589574007?pr=8872

@oxarbitrage oxarbitrage added the do-not-merge Tells Mergify not to merge this PR label Oct 10, 2024
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.

I haven't finished reviewing yet, but this is looking great so far. The well-factored code is appreciated.

Comment on lines +46 to +49
// FIXME: is this a correct calculation way?
// The longest Vec<BurnItem> we receive from an honest peer must fit inside a valid block.
// Since encoding the length of the vec takes at least one byte, we use MAX_BLOCK_BYTES - 1
(MAX_BLOCK_BYTES - 1) / BURN_ITEM_SIZE
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 This looks perfect, it just needs to be higher than the protocol limit without being unreasonably large, and this should be just ~0.1% more than the protocol limit.

Comment on lines +938 to +939
// FIXME: is it possible to convert V6 shielded data to V5?
// FIXME: add another function for V6, like transaction_to_fake_v6?
Copy link
Contributor

Choose a reason for hiding this comment

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

There's probably no need to convert v6 transactions to v5, it won't be used until test blocks with v6 transactions have been added, which may never happen. A function for converting to fake v6 transactions may be useful for testing or might not be necessary either.


// Denoted as `nExpiryHeight` in the spec.
writer.write_u32::<LittleEndian>(expiry_height.0)?;

Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: ZIP 230 is still a draft, but, if the explicit fee ends up being included it should be added here and as a field on the Transaction::V6 variant.

Everything else here looks good.

Comment on lines +178 to +180
writer.write_u8(self.is_finalized().as_u8())?;
self.notes().zcash_serialize(&mut writer)?;
self.asset_desc().zcash_serialize(&mut writer)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

These look like they're in the opposite order as they're listed in ZIP 230, but otherwise looks good, as does the serialization for IssueNote.

const NOTE_VALUE_SIZE: u64 = 4;
const RANDOM_SEED_SIZE: u64 = 32;
// FIXME: is this a correct way to calculate (simple sum of sizes of components)?
const NOTE_SIZE: u64 =
Copy link
Contributor

@arya2 arya2 Oct 10, 2024

Choose a reason for hiding this comment

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

It says 147 here but these add up to 143, this or the ZIP may need an update (probably this implementation, using a u64 for note value seems good).


impl TrustedPreallocate for Note {
fn max_allocation() -> u64 {
// FIXME: is this a correct calculation way?
Copy link
Contributor

Choose a reason for hiding this comment

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

Yep! This looks good.

Comment on lines +196 to +197
// FIXME: impl correct calculation
10
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks good, the function that calls max_allocation() (zcash_deserialize_external_count()) will deserialize and pre-allocate sequentially based on the actual counts, so until it goes through each item and reads their CompactSize, it'll just be pre-allocating memory for the pointers, if one of them is shorter than expected it'll return an error, and their combined real size can't be longer than the Codec's builder.max_len field, which is MAX_PROTOCOL_MESSAGE_LEN.

Suggested change
// FIXME: impl correct calculation
10
(MAX_BLOCK_BYTES - 1) / NOTE_SIZE

@dmidem dmidem closed this Oct 17, 2024
@dmidem dmidem deleted the switch-to-zsa-crates-nu6-txv6-gen branch October 17, 2024 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rust Area: Updates to Rust code C-feature Category: New features C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG do-not-merge Tells Mergify not to merge this PR P-Optional ✨
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants