Versioning
Versioning Circuits
Explicit tracking of versions helps in future updates that would require rewriting notes. Note that since data in notes is private, no central actor can assist in migrating the notes to a new version. For this reason, each future update must be either 100% backwards compatible w.r.t. the previous note structure, or, must involve an explicit note migration triggered by the user. Such a migration will essentially translate the note from the old format to a new format, without changing its content, but only bumping the version.
In circuits that deal with notes in version v
, constraints of the form are always included:
note_version == v
Both for the note being spent, and the new, just created note. Moreover the migration circuit must include constraints:
old_note_version == v
new_note_version == v+1
Versioning the Contract
Apart from note versioning, we also version the Shielder contract. Specifically we store a version
struct in the contract, whose one of the components is the note_version
. When sending transactions to the contract, the user explicitly specifies the contract version that he expects the transaction to be executed against. The contract will reject all transactions with incompatible versions.
One subtle point regarding the versioning in the contracts is that when using relayers, the user cannot really force a specific calldata in the transaction. That's why the user includes the contract version in a commitment as part of the proof. Even though the version is not used in any constraints in the circuit (the note_version
is used but we take it from the note, not from this input) we can include it in the witness, and because of non-malleability in Halo2, such a proof cannot be used to forge a different one with the version data replaced.
Versioning Clients
The Common App and other clients also have their own versioning schemes, however those are independent from the above.
Last updated