You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+2-3Lines changed: 2 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,12 +13,11 @@ Features:
13
13
14
14
* Multi-leaves existence / non-existence merkle proof
15
15
* Customizable hash function
16
+
* Storage backend agnostic
16
17
* Rust `no_std` support
17
18
18
19
This article describes algorithm of this data structure [An optimized compacted sparse merkle tree](SMT.md)
19
20
20
-
**Notice** this library is not stabled yet. The API and the format of the proof may be changed in the future. Make sure you know what you are doing before using this library.
21
-
22
21
## Construction
23
22
24
23
A sparse merkle tree is a perfectly balanced tree contains `2 ^ N` leaves:
Copy file name to clipboardExpand all lines: SMT.md
+10-7Lines changed: 10 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,12 +35,12 @@ In a naive sparse merkle tree construction, we usually pre-calculate the hash se
35
35
With optimization 1, we do not need the pre-calculated hash-set. For a default SMT, all the intermediate nodes are zero values. Thus, we only need to calculate the hash for non-zero nodes and return zero for the default nodes.
36
36
37
37
38
-
There’s only one issue that remains. The optimized hash function produces the same value from different key-value pairs, for example:
39
-
`merge(N, 0) == merge(0, N)`.
38
+
There’s only one issue that remains. The optimized hash function produces the same value from different key-value pairs, for example:
39
+
`merge(N, 0) == merge(0, N)`.
40
40
This behavior opens a weak point for the SMT. An attacker may construct a collision of merkle root from a faked key-value map.
41
41
42
-
To fix this, we use the result of `hash(key | value)` as a leaf’s hash, for examples:
the result is false because the `leaf_hash(N, 0)` is never equals to `leaf_hash(0, N)` if `N != 0`, the attacker can’t construct a collision attacking.
45
45
46
46
Additionally, we store `leaf_hash -> value` in a map to keep the reference to the original value.
@@ -63,7 +63,7 @@ pub struct BranchNode {
63
63
pubright:MergeValue,
64
64
}
65
65
```
66
-
When `left` and `right` are both zero, it's not needed to store this zero node.
66
+
When `left` and `right` are both zero, it's not needed to store this zero node.
67
67
68
68
We still face problem: too many branch nodes in real world. Assuming we have only one leaf node in SMT, there are still 255 branch nodes.
69
69
They are all ancestors of the only leaf node. The amount of branch nodes can be easily reached to millions when the leaf nodes grows to above 10k.
@@ -88,7 +88,10 @@ pub struct DefaultStore<V> {
88
88
}
89
89
```
90
90
91
-
If branch nodes are too many, it's better to implement a database backend. We suggest [RocksDB](http://rocksdb.org/): an embedded
92
-
persistent key-value store for fast storage.
91
+
If branch nodes are too many, it's better to implement a database backend. We suggest [RocksDB](http://rocksdb.org/): an embedded persistent key-value store for fast storage. Here is an example of RocksDB backend [implementation](https://github.com/quake/smt-rocksdb-store).
93
92
94
93
This store mechanics is only used in making SMT proof. It doesn't affect on-chain SMT verification which is still very fast and memory-efficient.
94
+
95
+
### Optimization 3: Shortcut nodes
96
+
97
+
We can optimize the storage space and performance by using shortcut nodes. A shortcut is a node that has only one leaf node, it can be merged with its parent node. The shortcut node is only used in the storage, it doesn't affect the verification process. We implement it as following algorithm: [Aergo Trie](https://github.com/aergoio/aergo/tree/master/pkg/trie). This algorithm is enabled by `trie` feature, which is disabled by default.
0 commit comments