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

feat(avm): ephemeral avm tree #9798

Merged
merged 9 commits into from
Nov 18, 2024
Merged

Conversation

IlyasRidhuan
Copy link
Contributor

@IlyasRidhuan IlyasRidhuan commented Nov 7, 2024

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:

  • Storage of a sparse, value-sorted data structure for the indexed tree leaf updates.
    • This would allow for fast low nullifier lookup (which will be the bottleneck for indexed tree operations)
  • Copy-on-write when forking
    • Some nested calls may not perform any operations on the trees (or perhaps a subset of tree). Forking all the information may unnecessarily consume memory for deeper nested contexts.

Copy link
Contributor Author

IlyasRidhuan commented Nov 7, 2024

@IlyasRidhuan IlyasRidhuan marked this pull request as ready for review November 7, 2024 11:58
@IlyasRidhuan IlyasRidhuan changed the title feat(avm): ephmeral avm tree feat(avm): ephemeral avm tree Nov 7, 2024
@IlyasRidhuan IlyasRidhuan force-pushed the ir/11-03-feat_avm_ephmeral_avm_tree branch from 5ac16a3 to 07f1316 Compare November 7, 2024 15:03
Copy link
Collaborator

@dbanks12 dbanks12 left a 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.

yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
Comment on lines 754 to 755
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));
Copy link
Collaborator

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

yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Show resolved Hide resolved
Comment on lines +678 to +649
* 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) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

consider renaming hashSubtree

Copy link
Contributor

@fcarreiro fcarreiro left a 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

yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.ts Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.test.ts Outdated Show resolved Hide resolved
const computedRoot = treeContainer.treeMap.get(treeId)!.getRoot();
expect(computedRoot.toBuffer()).toEqual(wsRoot);

const wsSiblingPath = await worldStateTrees.getSiblingPath(treeId, getSiblingIndex, true);
Copy link
Contributor

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?

yarn-project/simulator/src/avm/avm_tree.test.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.test.ts Outdated Show resolved Hide resolved
yarn-project/simulator/src/avm/avm_tree.test.ts Outdated Show resolved Hide resolved
@IlyasRidhuan IlyasRidhuan force-pushed the ir/11-03-feat_avm_ephmeral_avm_tree branch 5 times, most recently from df8067d to 4c99c3d Compare November 10, 2024 18:12
rightTree: Tree;
};

type Tree = Leaf | Branch;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dbanks12 removed EMPTY

@IlyasRidhuan IlyasRidhuan force-pushed the ir/11-03-feat_avm_ephmeral_avm_tree branch 4 times, most recently from da0ecb5 to 13e10c1 Compare November 13, 2024 00:57
@IlyasRidhuan IlyasRidhuan force-pushed the ir/11-03-feat_avm_ephmeral_avm_tree branch from 13e10c1 to d9eecce Compare November 13, 2024 15:49
Copy link
Collaborator

@dbanks12 dbanks12 left a 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!

Comment on lines +16 to +20
type PreimageWitness<T extends IndexedTreeLeafPreimage> = {
preimage: T;
index: bigint;
update: boolean;
};
Copy link
Collaborator

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

@IlyasRidhuan IlyasRidhuan force-pushed the ir/11-03-feat_avm_ephmeral_avm_tree branch from d9eecce to f152568 Compare November 14, 2024 21:29
@IlyasRidhuan IlyasRidhuan merged commit 41743d0 into master Nov 18, 2024
67 checks passed
@IlyasRidhuan IlyasRidhuan deleted the ir/11-03-feat_avm_ephmeral_avm_tree branch November 18, 2024 17:56
TomAFrench added a commit that referenced this pull request Nov 19, 2024
* 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
  ...
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.

3 participants