Skip to content

Commit 7c70731

Browse files
authored
Merge pull request #38 from quake/quake/upgrade-0.6.0
chore: upgrade to 0.6.0
2 parents 2641f59 + cb4bb4c commit 7c70731

File tree

3 files changed

+13
-11
lines changed

3 files changed

+13
-11
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sparse-merkle-tree"
3-
version = "0.5.4"
3+
version = "0.6.0"
44
authors = ["jjy <jjyruby@gmail.com>"]
55
edition = "2018"
66
license = "MIT"

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ Features:
1313

1414
* Multi-leaves existence / non-existence merkle proof
1515
* Customizable hash function
16+
* Storage backend agnostic
1617
* Rust `no_std` support
1718

1819
This article describes algorithm of this data structure [An optimized compacted sparse merkle tree](SMT.md)
1920

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-
2221
## Construction
2322

2423
A sparse merkle tree is a perfectly balanced tree contains `2 ^ N` leaves:
@@ -35,7 +34,7 @@ height:
3534
/ \ / \
3635
1 0 1 0 1
3736
/ \ / \ / \ / \
38-
0 0 1 0 1 ... 0 1 0 1
37+
0 0 1 0 1 ... 0 1 0 1
3938
0x00..00 0x00..01 ... 0x11..11
4039
```
4140

SMT.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ In a naive sparse merkle tree construction, we usually pre-calculate the hash se
3535
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.
3636

3737

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)`.
4040
This behavior opens a weak point for the SMT. An attacker may construct a collision of merkle root from a faked key-value map.
4141

42-
To fix this, we use the result of `hash(key | value)` as a leaf’s hash, for examples:
43-
`merge(N, leaf_hash(N, 0)) == merge(0, leaf_hash(0, N))`
42+
To fix this, we use the result of `hash(key | value)` as a leaf’s hash, for examples:
43+
`merge(N, leaf_hash(N, 0)) == merge(0, leaf_hash(0, N))`
4444
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.
4545

4646
Additionally, we store `leaf_hash -> value` in a map to keep the reference to the original value.
@@ -63,7 +63,7 @@ pub struct BranchNode {
6363
pub right: MergeValue,
6464
}
6565
```
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.
6767

6868
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.
6969
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> {
8888
}
8989
```
9090

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).
9392

9493
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

Comments
 (0)