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

Ergonomic MerkleTreeGadget #158

Merged
merged 11 commits into from
Dec 15, 2022
Merged

Ergonomic MerkleTreeGadget #158

merged 11 commits into from
Dec 15, 2022

Conversation

tessico
Copy link
Contributor

@tessico tessico commented Dec 13, 2022

Description

closes: ##88
as well as some indirect progress towards #142.

Note that non membership proofs are out of scope of this PR, but we can still close the referenced issue #88, if approved, since we already have a separate issue for non-membership proof constraints: #99.

Regarding the design, the initial refactor I had started doing was based on the API proposed by @alxiong in #88 - thanks a lot for this! You will see that it has changed in that methods don't accept native field elements/structs, but rather variables representing these items in the circuit. This was done for two reasons:

  • There would otherwise be no way to (efficiently) enforce multiple constraints with the same proof. E.g. given a Merkle path, it would be impossible (without allocating the path variables twice) to enforce that e.g. one element is a member and another is not.
  • API consistency. Most of our other APIs follow the format of create_<>_variable -> Result<SomeVariable, ()> and then using SomeVariable in enforcing constraints. I feel that this is a clean abstraction, and we should probably stick to not enforcing constraints "directly" from native items.

Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

  • Targeted PR against correct branch (main)
  • Linked to GitHub issue with discussion and accepted design OR have an explanation in the PR that describes this work.
  • Wrote unit tests
  • Updated relevant documentation in the code
  • Added a relevant changelog entry to the Pending section in CHANGELOG.md
  • Re-reviewed Files changed in the GitHub PR explorer

@tessico tessico requested a review from a team December 13, 2022 14:36
Copy link
Contributor

@alxiong alxiong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @tessico's choice of accepting Var instead of the original struct.

  1. I wonder if we should name rescue_merkle_tree.rs as append_only.rs for consistency with their non-circuit implementations?

primitives/src/circuit/merkle_tree/mod.rs Outdated Show resolved Hide resolved
primitives/src/circuit/merkle_tree/mod.rs Outdated Show resolved Hide resolved
Comment on lines 17 to 23
pub struct LeafVar {
/// Position of the leaf element in the MT. Serves as UID.
pub uid: Variable,
/// The value of the leaf element.
pub elem: Variable,
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should make this an associated type of trait MerkleTreeGadget instead, just like MerklePathVar?
The main rationale being that some MT's leaf (e.g. SMT) doesn't have to care about or even have uid. So it may suggest leaving the concrete instantiation to specific gadgets.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on this note, I noticed our current RescueSMT's digest_leaf is actually hashing [0, pos, elem], which I guess doesn't hurt, but when we treat it as a set (as we do when using SMT), we don't need that pos, no? @mrain

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. In case of set, elem is of type (). Information is stored in pos actually.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, right!

my original comment on making it an associated type might still be worth considering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good suggestion. Done in 7288912.

@tessico
Copy link
Contributor Author

tessico commented Dec 14, 2022

I wonder if we should name rescue_merkle_tree.rs as append_only.rs for consistency with their non-circuit implementations?

Yes, but after #142 lands. Currently the Rescue hash is "hardcoded" in the gadget implementation, so I think for now we should keep the name as is.
Later we can have append_only.rs and then instantiate a concrete one in the prelude of the circuit, like the native version does.

@alxiong

Copy link
Contributor

@alxiong alxiong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@mrain mrain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tessico tessico merged commit db2d5d8 into main Dec 15, 2022
@tessico tessico deleted the ergonomic-mt-gadget branch December 15, 2022 08:39
@tessico tessico mentioned this pull request Dec 23, 2022
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants