-
Notifications
You must be signed in to change notification settings - Fork 285
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
feat(avm): ephemeral avm tree #9798
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
5ac16a3
to
07f1316
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Lots of nits and some feedback on naming.
I don't have an easy time following some of this. In particular the frontier stuff. And I wish we didn't have to do so much of this from scratch and could reuse one of the existing merkle implementations that exists in the codebase.
I would get Alex's or Phil's eyes on this for approval since they have merkle trees fresher in mind.
switch (tree.tag) { | ||
case TreeType.BRANCH: { | ||
return insertPath.pop() === 0 | ||
? Branch(this._insertLeaf(value, insertPath, depth - 1, tree.leftTree, appendMode), tree.rightTree) | ||
: Branch(tree.leftTree, this._insertLeaf(value, insertPath, depth - 1, tree.rightTree, appendMode)); | ||
} | ||
case TreeType.LEAF: | ||
case TreeType.EMPTY: { | ||
const zeroLeaf = appendMode ? Leaf(this.zeroHashes[depth - 1]) : Empty(); | ||
return insertPath.pop() === 0 | ||
? Branch(this._insertLeaf(value, insertPath, depth - 1, zeroLeaf, appendMode), zeroLeaf) | ||
: Branch(zeroLeaf, this._insertLeaf(value, insertPath, depth - 1, zeroLeaf, appendMode)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd break these ternary operators up into ifs and assign the results of each _insertLeaf
to a meaningfully named variables like updatedLeftTree
, etc
* Recursively hashes the subtree | ||
* @param tree - The tree to be hashed | ||
* @param depth - The depth of the tree | ||
*/ | ||
public hashTree(tree: Tree, depth: number): Fr { | ||
switch (tree.tag) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider renaming hashSubtree
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of stuff! I cannot guarantee that I understand all of it, but tests seem reasonable.
Does it work? We'll know soon :D
const computedRoot = treeContainer.treeMap.get(treeId)!.getRoot(); | ||
expect(computedRoot.toBuffer()).toEqual(wsRoot); | ||
|
||
const wsSiblingPath = await worldStateTrees.getSiblingPath(treeId, getSiblingIndex, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there are not many, would it make sense to compare every single sibling path?
df8067d
to
4c99c3d
Compare
rightTree: Tree; | ||
}; | ||
|
||
type Tree = Leaf | Branch; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dbanks12 removed EMPTY
da0ecb5
to
13e10c1
Compare
13e10c1
to
d9eecce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that once we're happy with this implementation it MIGHT make sense to move it into a merkle library and not call it "Avm*". But for now this feels right. Nice work!
type PreimageWitness<T extends IndexedTreeLeafPreimage> = { | ||
preimage: T; | ||
index: bigint; | ||
update: boolean; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think this name isn't great. Elsewhere we use "witness" in the context of merkle trees to be leaf index & sibling path. I don't know what a better name is, but PreimageWitness doesn't feel right
d9eecce
to
f152568
Compare
* master: (67 commits) chore: Fix bad merge on AztecLMDBStore initializer feat: add persisted database of proving jobs (#9942) chore: Clean up data configuration (#9973) chore: remove public kernels (#10027) chore: misc cleanup, docs and renaming (#9968) feat: IPA Accumulator in Builder (#9846) chore(docs): Updates to token contract (#9954) test(avm): minor benchmarking (#9869) chore(ci): run `l1-contracts` CI in parallel with `build` step (#10024) chore: build acir test programs in parallel to e2e build step (#9988) chore: pull out `array_set` pass changes (#9993) feat(avm): ephemeral avm tree (#9798) fix: don't take down runners with faulty runner check (#10019) feat(docs): add transaction profiler docs (#9932) chore: hotfix runner wait (#10018) refactor: remove EnqueuedCallSimulator (#10015) refactor: stop calling public kernels (#9971) git subrepo push --branch=master noir-projects/aztec-nr git_subrepo.sh: Fix parent in .gitrepo file. [skip ci] chore: replace relative paths to noir-protocol-circuits ...
This adds forkable trees so that we can use them in the avm to handle context changes.
The existing native trees are missing the ability to arbitrarily fork from uncommitted state. This is a requirement for our one-tx processing as we need to be able to fork-rollback-fork when encountering a change in the avm context (e.g. in a nested call).
These trees store the difference between the initial tx state (stored in the native world state db) and the current ephmeral state during transaction processing. Queries are either handled by the ephemeral tree or proxied to the db.
Currently there are definitely some room for performance improvements. Namely: