[Proposal] Spending notes which haven't-yet been inserted

Progress with read requests

Read requests are now output from the App circuit and checked in the kernel (issue & PR w/ follow up tasks).

A read_request may reference a commitment created in a later iteration

@suyash67, @jean and I believe we discovered an issue with the implementation outlined in this post.

Consider this example:

  1. A::foo calls A::bar
  2. A::bar creates commitment C
  3. A::bar returns to A::foo which then reads C

Here, the initial kernel iteration will be for foo which reads C, but C won’t appear in new_commitments until the following kernel iteration for bar.

This means that a read_request in one kernel may reference a pending commitment that is not present in new_commitments until a later kernel iteration. While new_commitments get forwarded from one kernel iteration to the next, read_requests do not (at least in the current implementation).

Solution 1

Rework the private kernel to have one iteration per “frame”, where a frame ends when a nested call is made or returned from. Originally discussed here.

Solution 2

Modify the current kernel implementation to forward all unmatched read_requests (those that read a “pending” new_commitment but have not been matched to one yet) to the next kernel iteration. Each kernel can then check its own read_requests as well as the previous kernel’s against all new_commitments seen thus far.

This would require us to add read_requests to the private kernel’s public inputs. We would then we need to constrain that there be 0 unmatched read requests at the end of the final iteration. Ideally the last iteration should not even have read_requests in its public inputs. This would require a separate private_kernel_circuit_final with different public inputs.

Wondering if anyone else has ideas or if anyone has considered this?

2 Likes