Skip to content

Commit 35548cd

Browse files
authored
Update README.md
1 parent df02a88 commit 35548cd

File tree

1 file changed

+0
-23
lines changed

1 file changed

+0
-23
lines changed

README.md

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,6 @@ height:
4141

4242
The above graph demonstrates a sparse merkle tree with `2 ^ 256` leaves, which can mapping every possible `H256` value into leaves. The height of the tree is `256`, from top to bottom, we denote `0` for each left branch and denote `1` for each right branch, so we can get a 256 bits path, which also can represent in `H256`, we use the path as the key of leaves, the most left leaf's key is `0x00..00`, and the next key is `0x00..01`, the most right key is `0x11..11`.
4343

44-
We use a `H256` root and a map `map[(usize, H256)] -> (H256, H256)` to represent the tree, the map's key is node and its height, the map's values are node's children, an empty tree represented in an empty map plus a zero `H256` root.
45-
46-
To update a `key` with `value`, we walk the tree from `root` to `leaf`, push every non-zero sibling into `merkle_path` vector, since the tree height is `N = 256`, the `merkle_path` contains 256 siblings. Then we reconstruct the tree from bottom to top: `map[(height, parent)] = merge(lhs, rhs)`, after do 256 times calculation we got the new `root`.
47-
48-
A sparse merkle tree contains few efficient nodes and others are zeros, we can specialize the `merge` function for zero value. We redefine the `merge` function, only do the actual computing when `lhs` and `rhs` are both non-zero values, otherwise if one of them is zero, we just return another one as the result.
49-
50-
``` rust
51-
fn merge(lhs: H256, rhs: H256) -> H256 {
52-
if lhs.is_zero() {
53-
return rhs;
54-
} else if rhs.is_zero() {
55-
return lhs;
56-
}
57-
58-
// only do actual computing when lhs and rhs both are non-zero
59-
merge_hash(lhs, rhs)
60-
}
61-
```
62-
63-
This optimized `merge` function still has one issue, `merge(x, zero)` equals to `merge(zero, x)`, which means the merkle `root` is broken since an attacker can easily construct a collision of merkle root.
64-
65-
To fix this, instead of update `key` with an `H256` `value`, we use `hash(key | value)` as the value to merge, so for different keys, no matter what the `value` is, the leaves' hashes are unique. Since all leaves have a unique hash, nodes at each height will either merged by two different hashes or merged by a hash with a zero; for a non-zero parent, either situation we get a unique hash at the parent's height. Until the root, if the tree is empty, we get zero, or if the tree is not empty, the root must be merged from two hashes or a hash with a zero, because of the hash of two children nodes are unique, the root hash is also unique. Thus, an attacker can't construct a collision attack.
66-
6744
## License
6845

6946
MIT

0 commit comments

Comments
 (0)