Split aux tables based on size#504
Open
robknight wants to merge 2 commits into
Open
Conversation
ax0
approved these changes
May 15, 2026
Collaborator
|
If I understand this correctly, the saving comes from replacing:
I wonder if we can apply this change for all cases, and we can move back to a single table. |
ed255
added a commit
that referenced
this pull request
May 25, 2026
Redesign how public statements are handled. Previously public statements were a hashed list of consecutive statements. We had an area of the circuit to open all the public statements of input pods, and an area to copy statements to be public in the current pod. Now the public statements live in a tree of parametrizable depth. We remove the area of input pod public statements and the area of current pod public statements. Instead we introduce an operation to open a public statement from an input pod (which consumes a regular statement slot), which is needed when we want to use an input statement. And each statement slot can become a public statement of the current pod, with a limit on the total by a parameter field. Both the opening input pod statement and the making a statement public use tables, so the number of times such operations can be made is lower than the total number of statements. Moreover, a pod can start from an empty tree of statements and only output public statements generated in that pod, or it can extend the tree of statements from the first input pod, which allows us to carry statements forward in a recursive chain of pods at no cost. Aside from this change - I've removed the Copy operation because it's no longer needed. We used it previously to make a private or input statement public by copying it over the public area. But now any statement can be public. - Applied a bugfix I saw in #504 in `CustomPredicateVerifyQueryTarget::size` - Removed passing `sts_hash` in the serialize/deserialize operations, because that value is better derived from the list of statements for a simpler verification flow. - Renamed `self_statement` to `raw_statement` because we no longer have the concept of self in a pod (we only have it in a custom predicate module). The `raw_statement` is used to build the statement tree, and for introduction pods it has an empty placeholder instead of their verifier data hash that needs to be replaced by a normalization step. - Added a method to the Pod trait to get the public statement tree - The MainPodBuilder will automatically open an input pod statement if an operation depends on it and is not found in the previous statement. This makes the API behave like before. - Change how we distinguish MainPod from IntroPod. An IntroPod was previously detected by inspecting the first statement and looking for an intro statement with blank verifier data hash. Now this would require an opening, so I've extended the public inputs to include a field that signals when the pod is main. If the pod is main, it's verifier data hash must be in the VDSet; so no intro can lie about it. If it claims to be intro, when we open a statement we validate that it's indeed intro and place its verifier data hash inside.
6279b94 to
e49804b
Compare
e49804b to
fe21338
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The aux table holds supporting data for certain operations, including Merkle container and state transition ops, SignedBy, PublicKeyOf, and custom predicate operations. It has a fixed row size, based on the largest possible value. Most aux table entries are quite small -
MerkleTreeStateTransitionClaimTargetis 18 field elements, and all others are smaller. However,CustomPredicateVerifyQueryTargetis 314 field elements. Because of this outlier, the table rows are much larger than is needed for typical cases, making lookups more expensive than they need to be.This change splits
CustomPredicateVerifyQueryTargetout:custom_pred_verify_hashes) stores just the query hash for eachCustomPredVerifyentry, indexed by the sameaux_index.verify_custom_circuitlooks up the stored hash and compares it to a freshly-computed hash of(statement, op_type, op_args), instead of unhashing a wide row and doing flattened equality.Both tables are identical in length (every push to one is paired with a
Nonepadding push to the other), enforced via helpers on a newOperationAuxTablesstruct.This reduces measured gate count by 3445.