This repository has been archived by the owner on Feb 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 53
[Exploration] Using Celestia's SMT for Pocket Network V1? #74
Draft
Olshansk
wants to merge
26
commits into
celestiaorg:master
Choose a base branch
from
Olshansk:olsh_exploration
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
b574a50
Add Makefile with test_all property
Olshansk cef5d99
General comment updates before adding treehasher test
Olshansk 0e2da02
Added TestTreeHasherPath
Olshansk fed5f94
Slight simplifcation to digestLeaf
Olshansk 915a4e9
Added tests and updated code for treeHasher
Olshansk 0d8e5f1
Do not expose updateForRoot function
Olshansk 9cbd11d
Do not expose setRoot function
Olshansk 0e0808b
Do not expose deleteForRoot function
Olshansk 1ce3acc
Delete deleteForRoot altogether
Olshansk 3ea32eb
Added questions to deleteWithSideNodes
Olshansk dcb4743
Minor optimization to countCommonPrefix
Olshansk 9fb2fdb
Specified return types for sideNodesForRoot
Olshansk d2f0789
Remove getSiblingData from interface in sideNodesForRoot
Olshansk 3c5608f
Finished reading (but don't fully understand) sideNodesForRoot and up…
Olshansk f1bd40b
Finished reading through smt.go
Olshansk 093f1fb
Added personal checklist
Olshansk b0bd128
Very minor cleanup to MapStore
Olshansk fdb7138
Don't pass around a pointer to maps in the tests
Olshansk e5af727
Add questions and improve readability in smt.go
Olshansk 88ec5fa
Add questions and improve readability in treehasher.go
Olshansk 8a1793b
Add TODOs in README
Olshansk 77c9425
Commit before improving readability of updateWithSideNodes
Olshansk ee24777
INterim commit before dsplot
Olshansk ef6cebd
Got some sort of visualization going
Olshansk a8c621a
Remove OLSH logs
Olshansk 4765876
Some old changes
Olshansk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
.SILENT: | ||
|
||
help: | ||
printf "Available targets\n\n" | ||
awk '/^[a-zA-Z\-\_0-9]+:/ { \ | ||
helpMessage = match(lastLine, /^## (.*)/); \ | ||
if (helpMessage) { \ | ||
helpCommand = substr($$1, 0, index($$1, ":")-1); \ | ||
helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ | ||
printf "%-30s %s\n", helpCommand, helpMessage; \ | ||
} \ | ||
} \ | ||
{ lastLine = $$0 }' $(MAKEFILE_LIST) | ||
|
||
.PHONY: test_all | ||
## Run all the unit tests | ||
test_all: | ||
go test -v -count=1 ./... | ||
|
||
.PHONY: test_smt | ||
## Run all the ^TestSparseMerkleTree unit tests | ||
test_smt: | ||
go test -v -count=1 -run TestSparseMerkleTree ./... | ||
|
||
.PHONY: test_th | ||
## Run all the ^TestTreeHasher unit tests | ||
test_th: | ||
go test -v -count=1 -run TestTreeHasher ./... | ||
|
||
.PHONY: test_ms | ||
## Run all the ^TestMapStore unit tests | ||
test_ms: | ||
go test -v -count=1 -run TestMapStore ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,93 @@ | ||
# smt | ||
# Sparse Merkle Tree (smt) | ||
|
||
A Go library that implements a Sparse Merkle tree for a key-value map. The tree implements the same optimisations specified in the [Libra whitepaper][libra whitepaper], to reduce the number of hash operations required per tree operation to O(k) where k is the number of non-empty elements in the tree. | ||
A Go library that implements a Sparse Merkle Tree for a key-value map. The tree implements the same optimisations specified in the [Jellyfish Merkle Tree whitepaper][jmt whitepaper] originally designed for the [Libra blockchain][libra whitepaper]. It reduces the number of hash operations required per tree operation to `O(k)` where `k` is the number of non-empty elements in the tree. | ||
|
||
[![Tests](https://github.com/celestiaorg/smt/actions/workflows/test.yml/badge.svg)](https://github.com/celestiaorg/smt/actions/workflows/test.yml) | ||
[![codecov](https://codecov.io/gh/celestiaorg/smt/branch/master/graph/badge.svg?token=U3GGEDSA94)](https://codecov.io/gh/celestiaorg/smt) | ||
[![GoDoc](https://godoc.org/github.com/celestiaorg/smt?status.svg)](https://godoc.org/github.com/celestiaorg/smt) | ||
|
||
## Installation | ||
|
||
```bash | ||
go get github.com/celestiaorg/smt@master | ||
``` | ||
|
||
## Example | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"crypto/sha256" | ||
"fmt" | ||
"crypto/sha256" | ||
"fmt" | ||
|
||
"github.com/celestiaorg/smt" | ||
"github.com/celestiaorg/smt" | ||
) | ||
|
||
func main() { | ||
// Initialise two new key-value store to store the nodes and values of the tree | ||
nodeStore := smt.NewSimpleMap() | ||
valueStore := smt.NewSimpleMap() | ||
// Initialise the tree | ||
tree := smt.NewSparseMerkleTree(nodeStore, valueStore, sha256.New()) | ||
|
||
// Update the key "foo" with the value "bar" | ||
_, _ = tree.Update([]byte("foo"), []byte("bar")) | ||
|
||
// Generate a Merkle proof for foo=bar | ||
proof, _ := tree.Prove([]byte("foo")) | ||
root := tree.Root() // We also need the current tree root for the proof | ||
|
||
// Verify the Merkle proof for foo=bar | ||
if smt.VerifyProof(proof, root, []byte("foo"), []byte("bar"), sha256.New()) { | ||
fmt.Println("Proof verification succeeded.") | ||
} else { | ||
fmt.Println("Proof verification failed.") | ||
} | ||
// Initialise 2 new key-value store to stores the nodes and values of the tree | ||
nodeStore := smt.NewSimpleMap() // Mapping from hash -> data; | ||
valueStore := smt.NewSimpleMap() // Mapping from node_path -> node_value; a path can be retrieved using the digest of the key | ||
|
||
// Initialise the smt | ||
tree := smt.NewSparseMerkleTree(nodeStore, valueStore, sha256.New()) | ||
|
||
// Update the key "foo" with the value "bar" | ||
_, _ = tree.Update([]byte("foo"), []byte("bar")) | ||
|
||
// Generate a Merkle proof for foo=bar | ||
proof, _ := tree.Prove([]byte("foo")) | ||
root := tree.Root() // We also need the current tree root for the proof | ||
|
||
// Verify the Merkle proof for foo=bar | ||
if smt.VerifyProof(proof, root, []byte("foo"), []byte("bar"), sha256.New()) { | ||
fmt.Println("Proof verification succeeded.") | ||
} else { | ||
fmt.Println("Proof verification failed.") | ||
} | ||
} | ||
``` | ||
|
||
## Development | ||
|
||
Run `make` to see all the options available | ||
|
||
## General Improvements / TODOs | ||
|
||
- [ ] Use the `require` test module to simplify unit tests; can be done with a single clever regex find+replace | ||
- [ ] Create types for `sideNodes`, `root`, etc... | ||
- [ ] Add an interface for `SparseMerkleProof` so we can return nils and not access vars directly | ||
- [ ] Add an interface for `SparseMerkleTree` so it's clear how we should interact with it | ||
- [ ] If we create an interface for `TreeHasher`, we can embed it in `SparseMerkleTree` and then avoid the need to write things like `smt.th.path(...)` everywhere and use `smt.path(...)` directly. | ||
- [ ] Consider splitting `smt.go` into `smt_ops.go` and `smt_proofs.go` | ||
- [ ] Functions like `sideNodesForRoot` and `updateWithSideNodes` need to be split into smaller more compartmentalized functions | ||
|
||
[libra whitepaper]: https://diem-developers-components.netlify.app/papers/the-diem-blockchain/2020-05-26.pdf | ||
[jmt whitepaper]: https://developers.diem.com/papers/jellyfish-merkle-tree/2021-01-14.pdf | ||
|
||
### [Delete me later] personal checklist | ||
|
||
- [x] ├── LICENSE | ||
- [x] ├── Makefile | ||
- [x] ├── README.md | ||
- [ ] ├── bench_test.go | ||
- [ ] ├── bulk_test.go | ||
- [ ] ├── deepsubtree.go | ||
- [ ] ├── deepsubtree_test.go | ||
- [ ] ├── fuzz | ||
- [ ] │ ├── delete | ||
- [ ] │ │ └── fuzz.go | ||
- [ ] │ └── fuzz.go | ||
- [x] ├── go.mod | ||
- [x] ├── go.sum | ||
- [x] ├── mapstore.go | ||
- [x] ├── mapstore_test.go | ||
- [x] ├── options.go | ||
- [ ] ├── oss-fuzz-build.sh | ||
- [ ] ├── proofs.go | ||
- [ ] ├── proofs_test.go | ||
- [x] ├── smt.go | ||
- [ ] ├── smt_test.go | ||
- [x] ├── treehasher.go | ||
- [x] ├── treehasher_test.go | ||
- [x] └── utils.go |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
module github.com/celestiaorg/smt | ||
|
||
go 1.14 | ||
|
||
require github.com/stretchr/testify v1.8.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This library is not based on JMT, just an optimized SMT. The JMT was introduced after the original Libra whitepaper, which is basically an optimized SMT but with further optimizations on the storage layer (storing it as a 16-ary tree, etc), which we don't make here yet. The original Libra whitepaper mentioned an optimized SMT, but did not introduce the JMT (with extra storage optimizations).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a JMT is just an SMT with r=16 + RocksDB + versioned keys.