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

Separate Noir and Noir<>TS concerns from Serialize #7728

Open
nventuro opened this issue Aug 1, 2024 · 0 comments
Open

Separate Noir and Noir<>TS concerns from Serialize #7728

nventuro opened this issue Aug 1, 2024 · 0 comments
Labels
team-fairies Nico's team
Milestone

Comments

@nventuro
Copy link
Contributor

nventuro commented Aug 1, 2024

We currently use the Serialize and Deserialize traits to convert Noir structs to/from arrays of fields. This is done in multiple places, typically to:

  • read/write a value to public storage
  • compute the hash of a value
  • send/recieve values in oracle calls

This is highly problematic because these use cases have radically different tradeoffs. When interacting with storage we want packed representations to minimize DA costs, which are custom and result in extra constraints/gas. Depending on the hash function used, it may similarly be desirable to spend constraints/gas compressing the input to then execute the hash over a smaller array. But when sending or receiving objects via oracles, size is entirely irrelevant: what we want instead is minimal constraints and gas, and to keep the method standard so that it can be replicated by the oracle resolver (PXE in our case).

This is currently causing issues: U128 is internally represented as two Field limbs that store u64s, but when serialized it is converted into a single field (reducing the array length from 2 to 1). However, if one tries to e.g. have a contract function receive a U128, the oracle resolvers will throw runtime errors as they realize the mismatch between the expected TS serialization and the one that is actually done in Noir. Other objects such as ScheduledDelayChange similarly perform tight packing in order to minimize storage requirements - this only works because they don't happen to be exposed to the oracles.

I think a reasonable path forward is to acknowledge these as two different use cases, and to split the serialization implementations. We could keep serialize for things like public storage etc, and have a second set of traits e.g. ToTsArray that must follow the standard serialization algorithm. Functions like pack/unpack would take TsArray wrappers instead of a plain Field array, and we'd detect errors that way. Eventually we could use #[derive] to automatically generate this trait, though I'd argue that manually rolling it out would already provide large benefits today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-fairies Nico's team
Projects
Status: Todo
Development

No branches or pull requests

1 participant