kroma-network / go-ethereum

go-ethereum for Kroma
GNU Lesser General Public License v3.0
44 stars 23 forks source link

implementation zk merkle tree #44

Closed jyc228 closed 8 months ago

jyc228 commented 1 year ago

Rationale

While implementing SnapSync(#19) , I needed a data structure where the left and right nodes of the tree were tree node pointers rather than hashes, so I started implementing a new tree. We measured its performance and it was better than the existing zktrie, so we implemented generalizations and additional interfaces with the possibility of using it commonly in GETH in the future.

Implementation

Compared to traditional zktrie, it has the following differences

  1. The left and right nodes of the parent node are not Hash: In zktrie, the children are always hash nodes, which means you always have to read and decode the blob with a hash every time you visit a node.
  2. The tree hash is not always calculated: In zktrie, the hash of every node in the visited path is recalculated every time the tree is modified. This causes a significant performance impact. The newly implemented tree performs well because it does not compute hashes during tree modification, but it does not retain the hashes of nodes abandoned along the way.
  3. Create separate node structures for each type and introduce the TreeNode interface
  4. Added HashNode type: If you implement a new tree with only EmptyNode, ParentNode, and LeafNode, you need to read all tree nodes on tree load because of the change history mentioned in 1. To prevent this, we added the HashNode.

Benchmark test results (input count : 100) zk merkle tree (zktrie compatibility mode) : Due to change 2, the newly implemented tree will not be able to provide data if intermediate states of the tree are required. Compatibility mode will match the behavior of the existing zktrie.

test1 ns/op b/op allocs/op
zktrie 1120 1054000 1364579 31074
zk merkle tree (zktrie compatibility mode) 1518 777902 978421 21859
zk merkle tree 3123 380472 483110 10270
test2 ns/op b/op allocs/op
zktrie 1128 1060267 1364471 31073
zk merkle tree (zktrie compatibility mode) 1532 778894 978350 21858
zk merkle tree 3084 379690 483087 10270
test3 ns/op b/op allocs/op
zktrie 1146 1059020 1364455 31073
zk merkle tree (zktrie compatibility mode) 1526 785060 978417 21859
zk merkle tree 3097 388190 483095 10270