Skip to content

Refactor issue/burn validation for Zebra asset state integration#199

Open
dmidem wants to merge 14 commits intozsa1from
issue-burn-zebra-integration
Open

Refactor issue/burn validation for Zebra asset state integration#199
dmidem wants to merge 14 commits intozsa1from
issue-burn-zebra-integration

Conversation

@dmidem
Copy link

@dmidem dmidem commented Nov 26, 2025

This PR refactors Orchard’s issue/burn validation so Zebra can call it directly when maintaining its issued_assets state and when processing checkpointed blocks.

The changes:

  • extend issuance and burn error types (derives + a few new variants)
  • make state lookup callbacks FnMut so Zebra can keep a local cache
  • split verify_issue_bundle to reuse core validation as verify_trusted_issue_bundle (no sighash/signature, for checkpoints)
  • update validate_bundle_burn to check burns against the asset state and return updated AssetRecords, making it symmetric with verify_issue_bundle

This change refactors Orchard issuance and burn validation so Zebra can
reuse it for its issued_assets global state and checkpoint handling.

- Add derives and a few new error variants for issuance and burn so Zebra
  can surface state-related failures explicitly.
- Change state lookup callbacks to FnMut to allow caching on the Zebra side.
- Split verify_issue_bundle into signature checking plus a
  verify_trusted_issue_bundle variant for checkpointed blocks.
- Make burn validation state-aware and return updated AssetRecord values,
  symmetric to issuance.
@QED-it QED-it deleted a comment from what-the-diff bot Nov 26, 2025
Copy link
Collaborator

@PaulLaux PaulLaux left a comment

Choose a reason for hiding this comment

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

Overall good. Posted comments

verify_trusted_issue_bundle(bundle, get_global_records, first_nullifier)
}

// FIXME: move it and add tests ...
Copy link
Collaborator

Choose a reason for hiding this comment

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

remove or fix

Copy link
Author

Choose a reason for hiding this comment

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

Fixed (removed the comment).


/// Strips reference notes, keeping only amounts (reference notes contain
/// randomness and can't be compared directly).
fn strip_reference_notes(
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's call it remove_reference_notes()

Copy link
Author

@dmidem dmidem Feb 16, 2026

Choose a reason for hiding this comment

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

Fixed (renamed and updated the doc comment).

Comment on lines 134 to 135
/// Builds a BTreeMap of asset states from an array of (asset_desc, supply) tuples.
///
Copy link
Collaborator

Choose a reason for hiding this comment

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

Provide more context here. What is state in the context of orchard?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's call it build_tree() and avoid the term state and the discussion around it as much as possible for orchard.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed. As we discussed, I renamed the build_state function to mock_issuance_records. I also replaced the remaining mentions of “state” in comments with “global issuance state”, following ZIP 0227’s terminology (Global Issuance State section).

/// # Returns
///
/// A `BTreeMap<AssetBase, AssetRecord>` containing the asset records.
fn build_state(data: &[(&[u8], u64)]) -> BTreeMap<AssetBase, AssetRecord> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this untyped style data: &[(&[u8], u64)] does not work for Orchard. Please create a properly typed function signature.

Copy link
Author

@dmidem dmidem Feb 17, 2026

Choose a reason for hiding this comment

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

Fixed - replaced the tuple with a new struct:

struct AssetSupply {
    asset: AssetBase,
   supply: u64,
}

use crate::keys::{FullViewingKey, Scope, SpendingKey};
use rand::rngs::OsRng;

let mut rng = OsRng;
Copy link
Collaborator

Choose a reason for hiding this comment

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

consider deterministic seed here

write!(f, "Cannot burn an asset with a zero value.")
}
BurnError::AssetNotFoundInState => write!(f, "Asset not found in state."),
BurnError::InsufficientSupply => write!(f, "Insufficient supply for burn"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This one does not end with period . but all the others does. Please check Orchard and align the style (I think we dont need . at the end)

Copy link
Author

@dmidem dmidem Feb 16, 2026

Choose a reason for hiding this comment

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

Fixed (removed trailing periods in the fmt::Display strings).

I checked Orchard’s style and it’s mixed, but doc comments on error enum variants usually include periods (for example BuildError, SpendError, and OutputError in [builder.rs](https://github.com/zcash/orchard/blob/main/src/builder.rs)). The fmt::Display messages are more inconsistent and use trailing periods less often. So I removed trailing periods from the error strings, and kept periods in the error enum variant doc comments.

Comment on lines +19 to +22
/// Asset not found in state
AssetNotFoundInState,
/// Insufficient supply for burn
InsufficientSupply,
Copy link
Collaborator

Choose a reason for hiding this comment

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

align . usage in docstrings as in Orchard

Copy link
Author

@dmidem dmidem Feb 16, 2026

Choose a reason for hiding this comment

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

Fixed (added the missing trailing periods, see my previous comment).

reference_note: current_record.reference_note,
};

if new_records.insert(asset, new_record).is_some() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

In this new version, you check if the asset is duplicated at the end, after get_current_record(&asset). Consider checking for duplicates (without insert) early and avoid expensive operations on duplicated assets.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed - replaced with the following check before get_current_record(&asset):

if new_records.contains_key(&asset) {
    return Err(BurnError::DuplicateAsset);
}

@dmidem dmidem force-pushed the issue-burn-zebra-integration branch from d67d5ca to 5bc85a4 Compare February 17, 2026 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants