Skip to content

Conversation

@dmidem
Copy link
Collaborator

@dmidem dmidem commented Nov 27, 2024

This pull request integrates the zsa-issued-assets branch into the zsa-integration-consensus branch by creating a new zsa-integration-state branch based on zsa-integration-consensus.

The zsa-issued-assets branch was merged into zsa-integration-state, during which all merge conflicts were resolved, and compilation errors were fixed to ensure the code builds successfully.

Additionally, several bugs introduced by the zsa-issued-assets branch were identified and addressed using the newly implemented zebra-consensus check_zsa_workflow unit test from the zsa-integration-consensus.

arya2 and others added 17 commits November 12, 2024 01:07
…callyVerifiedBlock types, updates `IssuedAssetsChange::from_transactions()` method return type
…f BE for amount, read amount after asset base)
…ror in the function of the crate (this may not be a fully correct fix). Add a couple of FIXME comments explaining the problem.
@dmidem dmidem requested review from PaulLaux and arya2 November 27, 2024 10:21
…64 to prevent serialization errors and enable defining BurnItem in orchard, facilitating its reuse along with related functions
Copy link
Collaborator

@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 looks good, thank you for catching the mistake around converting negative i128s to u64s.

I addressed some of the FIXMEs added here in #32 after adding the RPC method. I'm happy to remove the issued_assets_change field on SemanticallyVerifiedBlock and get the changes from block transactions directly valid_burns_and_issuance() and prepare_issued_assets_batch(), the current code there is needlessly complicated (was this the simplification you were asking about during the Qedit-ZF sync?)

// TODO: Reference ZIP
0.. => signed.try_into().ok().map(Self::Issuance),
..0 => signed.try_into().ok().map(Self::Burn),
// FIXME: (-signed) - is this a correct fix?
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is correct, thank you for catching it!

})
.unwrap_or_default()
.into_iter()
// FIXME: We use 0 as a value - is that correct?
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's correct but overly complicated, it should be refactored.

ValueCommitment::with_asset(pallas::Scalar::zero(), amount, &asset)
ValueCommitment::with_asset(
pallas::Scalar::zero(),
// FIXME: consider to use TryFrom and return an error instead of using "expect"
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be a u64 so the conversion should be infallible.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That makes sense. But to make it work, the new ValueCommitment::with_asset constructor I added earlier should accept the value as a NoteValue instead of Amount (which is i64-based). I've fixed that and pushed the change into the zsa-integration-state branch.

Comment on lines 59 to 65
// FIXME: Not sure: it looks like semantically_verified.issued_assets_changes is already
// filled with burn and issuance items in zebra-consensus, see Verifier::call function in
// zebra-consensus/src/transaction.rs (it uses from_burn and from_issue_action AssetStateChange
// methods from ebra-chain/src/orchard_zsa/asset_state.rs). Can't it cause a duplication?
// Can we collect all change items here, not in zebra-consensus (and so we don't need
// SemanticallyVerifiedBlock::issued_assets_changes at all), or performing part of the
// checks in zebra-consensus is important for the consensus checks order in a some way?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't it cause a duplication?

It wouldn't be duplicated since the previous loop isn't mutating the asset states, it's just loading them into memory.

Can we collect all change items here, not in zebra-consensus

Yep, I'll try to make this change.

Comment on lines 79 to 80
// hand, there needs to be a check that denies duplicated burn records for the same
// asset inside the same transaction.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It does need to check that there are no duplicate burns in a single transaction somewhere, but that could be validated during deserialization or semantic validation, and this should update the asset state correctly otherwise.

I think we should update the Burn type to be Burn(HashMap<AssetBase, NoteValue>) and return an error during deserialization if any asset base is burned twice in the same transaction.

Copy link
Collaborator Author

@dmidem dmidem Dec 3, 2024

Choose a reason for hiding this comment

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

That's a good idea to use a HashMap to ensure the uniqueness of AssetBase at the type level (the uniqueness would be validated in the deserialization function). However, I see two downsides:

  1. Using a HashMap makes the burn.rs module code more bloated, as, for example, we can't directly take advantage of the automatic vector serialization provided by ZcashSerialize and ZcashDeserialize and have to implement it manually. But this isn't a major issue - I attempted to implement it today.

  2. A more serious problem is that HashMap does not preserve the order of items. If we deserialize the transaction and then serialize it back or calculate the hash, the result would differ because the order of the burn items would change (most likely different, to be precise). To resolve this issue, we would need to add a new requirement to the specification that burn items must be sorted in the transaction by the bytes of AssetBase, for example.

In my opinion, we could continue using a Vec for now but perform uniqueness validation within/after the deserializer. And we already have a burn validation function in the orchard crate. I will add this check.

…tead of amount (with_asset is used to process orchard burn) - this allows avoiding the use of try_into for burn in binding_verification_key function
@dmidem
Copy link
Collaborator Author

dmidem commented Dec 3, 2024

This looks good, thank you for catching the mistake around converting negative i128s to u64s.

I addressed some of the FIXMEs added here in #32 after adding the RPC method. I'm happy to remove the issued_assets_change field on SemanticallyVerifiedBlock and get the changes from block transactions directly valid_burns_and_issuance() and prepare_issued_assets_batch(), the current code there is needlessly complicated (was this the simplification you were asking about during the Qedit-ZF sync?)

Great, thanks @arya2. Regarding the simplification I mentioned, my main idea was to reuse our work from the orchard crate, such as the burn validation I referred to earlier here, and also the AssetSupply type (supply_info.rs - it's very similar to your AssetState). But, about AssetSupply, after discussing it with @PaulLaux, it seems that removing it from orchard in favor of the AssetState functionality you implemented in Zebra might be preferable.

@dmidem dmidem changed the title ZSA integration (step 8): Merge zsa-issued-assets into zsa-integration-consensus with bug fixes ZSA integration (stage 2) - state Jun 8, 2025
@dmidem dmidem changed the title ZSA integration (stage 2) - state ZSA integration (stage 2) - Issuance/burn state Jun 8, 2025
@dmidem dmidem changed the title ZSA integration (stage 2) - Issuance/burn state ZSA integration (stage 2) - Issed assets state Jun 8, 2025
fn as_bytes(&self) -> Self::Bytes {
[
vec![self.is_finalized as u8],
self.total_supply.to_be_bytes().to_vec(),
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@arya2 (Link): This will panic, should be 17 bytes.

Update: The burn amount should be a u64.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Looks like resolved.

self.issued_assets.get(asset_base).cloned()
}

/// Remove the History tree index at `height`.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@arya2 (Link): @dmidem I think it would be simpler to keep the issued assets maps on each ContextuallyValidatedBlock partial relative to the previous block instead of making them partial relative to the finalized tip, but if they need to be relative to the finalized tip, copying the AssetBases for every block would multiply the non-finalized state's theoretical max memory use, so those should go in Arcs.

Suggested change
/// Remove the History tree index at `height`.
/// When a block with the provided `transactions` and partial `issued_assets` state is removed
/// from the chain tip, revert its changes from the [`Chain`]'s partial issued assets state.
///
/// When a block is removed from the chain root to be committed to the finalized state, any
/// assets in its partial `issued_assets` with an asset state matching the one in the chain's
/// partial issued assets map is removed from the chain's partial issued assets map (since that
/// it should match the finalized issued asset state.)

@dmidem dmidem changed the title ZSA integration (stage 2) - Issed assets state ZSA integration (stage 2) - Issued assets state Jun 9, 2025
@dmidem dmidem force-pushed the zsa-integration-state branch from 0a09a70 to 43ea314 Compare June 15, 2025 20:34
@dmidem dmidem force-pushed the zsa-integration-state branch from 11e1c3e to 3ab6b56 Compare June 16, 2025 07:48
@dmidem dmidem changed the base branch from zsa-integration-consensus to zsa1 June 23, 2025 11:12
@dmidem dmidem added the stage2 label Jul 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants