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

Make circuits async: JS side #735

Closed
mitschabaude opened this issue Feb 16, 2023 · 3 comments · Fixed by #1477
Closed

Make circuits async: JS side #735

mitschabaude opened this issue Feb 16, 2023 · 3 comments · Fixed by #1477
Assignees
Labels
breaking Issues that will lead to breaking changes eng-priority Issues that seem high priority to one engineer user-priority Issues that seem high priority to one or more users v1 Prerequisite for o1js v1.0 zkDSL Issues to improve the core experience of writing circuits

Comments

@mitschabaude
Copy link
Member

mitschabaude commented Feb 16, 2023

Why:

  • @mrmr1993 might work on allowing async circuits in Pickles
  • Smart contracts need the result of async computations inside circuits (fetch accounts / best chain), and currently have error-prone workarounds; huge simplification if we could just fetch
  • Users would also like to do async operations, and have no workarounds currently
@mitschabaude mitschabaude added the eng-priority Issues that seem high priority to one engineer label Feb 16, 2023
@maht0rz
Copy link
Contributor

maht0rz commented Mar 10, 2023

Having an async Circuit.witness could enable much nicer UX on 3rd party library side

@maht0rz
Copy link
Contributor

maht0rz commented Oct 6, 2023

We've run into a performance bottleneck again while building https://protokit.dev, I'll try to briefly explain what exactly we have to do in the current block production pipeline and how async witnesses could help.

For Smart Contracts / zkApps the on-chain state is preloaded at once (all 8 fields) and therefore synchronously accessible within the smart contract method, e.g. using a synchronous Provable.witness(Field, () => Field(1)). This is only possible since the on-chain state size is known upfront.

If the execution of a smart contract relies on additional private inputs (not known upfront), that depend on the partial result of computation of the method, and these inputs have to be fetched from somewhere - API, DB, etc. Then the code looks something like this:

// in @method()

// some in circuit computation of known inputs
function getUser(a: Field, b: Field) {
  const key = Poseidon.hash([a,b]);
  
  // non-async witness
  const user = Provable.witness(User, () => {
     // access the user data statically, since the witness is synchronous, the data must be prefetched
     const data = prefetchedData[key];
     return new User(data)
  })
  
  // alternative async witness (not possible today)
  const user = Provable.witness(User, async () => {
     // access the user data from an API directly, since we can pause the circuit until the witness is resolved
     const data = await fetch("https://my-api.com/" + key)
     return new User(data)
  })
}

What the synchronous witness approach results in is that if we can't reliably determine what data needs to be prefetched for the circuit execution, we end up with re-running the circuit to try and populate all the prefetched data one by one. This becomes especially noticeable if prefetching of "data 2" relies on the result of prefetching "data 1".

To sum it up, async witnesses would greatly increase the performance of Protokit block production by decreasing the complexity of the implementation as well.

@mitschabaude mitschabaude added the user-priority Issues that seem high priority to one or more users label Oct 6, 2023
@mitschabaude
Copy link
Member Author

mitschabaude commented Oct 6, 2023

Note: async witness is easy to implement purely in o1js if only we have async circuits

@mitschabaude mitschabaude added the zkDSL Issues to improve the core experience of writing circuits label Dec 13, 2023
@mitschabaude mitschabaude added the breaking Issues that will lead to breaking changes label Jan 30, 2024
@garwalsh garwalsh added the v1 Prerequisite for o1js v1.0 label Jan 30, 2024
@mitschabaude mitschabaude self-assigned this Feb 6, 2024
@mitschabaude mitschabaude reopened this Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Issues that will lead to breaking changes eng-priority Issues that seem high priority to one engineer user-priority Issues that seem high priority to one or more users v1 Prerequisite for o1js v1.0 zkDSL Issues to improve the core experience of writing circuits
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants