refactor!: bundle private/public i/o into action structs - #604
Conversation
Arjentix
left a comment
There was a problem hiding this comment.
Like the approach, much cleaner now.
Left some minor comments, will wait for undrafting and then will approve
| pub struct PublicActionWithOwner { | ||
| pub account_id: AccountId, | ||
| pub post_state: Account, | ||
| } |
There was a problem hiding this comment.
Name of the struct does not reflect what's inside I think
There was a problem hiding this comment.
Renamed to PublicActionWIthID, agreed that Owner is a vague term with program ownership alongside authorization
| public_account_ids: public_actions.iter().map(|a| a.account_id.into()).collect(), | ||
| nonces: nonces.iter().map(|x| x.0).collect(), | ||
| public_post_states: public_post_states.into_iter().map(Into::into).collect(), | ||
| encrypted_private_post_states: encrypted_private_post_states | ||
| .into_iter() | ||
| .map(Into::into) | ||
| public_post_states: public_actions.into_iter().map(|a| a.post_state.into()).collect(), | ||
| encrypted_private_post_states: private_actions | ||
| .iter() | ||
| .map(|a| a.encrypted_post_state.clone().into()) | ||
| .collect(), | ||
| new_commitments: new_commitments.into_iter().map(Into::into).collect(), | ||
| new_nullifiers: new_nullifiers | ||
| new_commitments: private_actions.iter().map(|a| a.commitment.clone().into()).collect(), | ||
| new_nullifiers: private_actions |
There was a problem hiding this comment.
I think It's worth changing this whole struct the same way you changed the core struct.
In case of any problems on Explorer side you can always use Claude, haha
There was a problem hiding this comment.
should be better now! the message format has been changed accordingly!
f3d58b4 to
ed6349e
Compare
Benchmark for d017a1fClick to view benchmark
|
moudyellaz
left a comment
There was a problem hiding this comment.
Left two comments. The three failing CI jobs look like infra (archive extraction + GitHub rate limit fetching risc0), probably just need a rerun.
| pub struct PrivateAction { | ||
| pub nullifier: Nullifier, | ||
| pub root: CommitmentSetDigest, | ||
| pub commitment: Commitment, |
There was a problem hiding this comment.
One thing worth guarding here: after obfuscate_output_ordering, this commitment no longer belongs to this action's nullifier/encrypted_post_state (that's #561's unlinking doing its job), but the struct shape suggests they're paired, and the indexer protocol mirrors it downstream. Could commitments move out to a separate Vec<Commitment>, since nullifier/root/note are truly paired and commitments are an independent set? If you'd rather keep the bundling, a doc note on this field at both definition sites would save a future consumer from re-linking them.
There was a problem hiding this comment.
I think I would rather keep the binding, otherwise this reintroduces the issue of length-matching.
But I agree that a doc addition would be nice!
There was a problem hiding this comment.
Should be addressed in 0e957b5
Let me know if there are any other places you want me to document this
| pub struct Message { | ||
| pub public_account_ids: Vec<AccountId>, | ||
| pub public_actions: Vec<PublicActionWithID>, | ||
| pub nonces: Vec<Nonce>, |
There was a problem hiding this comment.
nonces is the one parallel vector left after this refactor, positionally paired with public_actions. Could nonce live inside PublicActionWithID, or does the signing/serialization format constrain it?
There was a problem hiding this comment.
I agree that it would be nice to pair these! Indeed, the signing format currently seems to narrow it as the nonces for signature-checking are gotten by position from the nonces vector. There is probably some nice way to refactor this as well, but it seemed to be something to be undertaken in parallel, I concentrated only on the pre-post state pairing here.
8539fb9 to
b5d5d86
Compare
BREAKING! Before: The message format for private transactions included separate fields for private transaction state identifiers such as commitments and nullifiers. After: The commitments/nullifiers/ciphertexts are bound in an Action struct, likewise for public state-bearing messages. Mitigation: assume incoming messages are in a newly-specified format.
9a2c9a2 to
846e194
Compare
🎯 Purpose
This refactors the message and the PPC output structs, enforcing the bijection between pre and post-states on the struct level. Before, e.g. having separate vectors for
new_commitmentsandnew_nullifierswould require being careful about their length mismatch.This refactor reduces the mismatch possibilities by making sure that all pre and post state fields for public and private accounts come paired in an appropriate struct. E.g. the privacy-preserving circuit output struct becomes:
The name
Actionsis taken from ZCash as a stand-in, feel free to suggest better naming.⚙️ Approach
🧪 How to Test
RISC0_DEV_MODE=1 cargo nextest run --workspace --exclude integration_tests --all-features --no-fail-fast📋 PR Completion Checklist
Mark only completed items. A complete PR should have all boxes ticked.