Skip to content

Commit c50a9a6

Browse files
committed
Refactor, clean up types, Readme
1 parent dba215c commit c50a9a6

20 files changed

+1397
-1614
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,21 @@ import (
1919
)
2020

2121
func main() {
22-
// Initialise two new key-value store to store the nodes and values of the tree
22+
// Initialise two new key-value store to store the nodes of the tree
23+
// (Note: the tree only stores hashed values, not raw value data)
2324
nodeStore := smt.NewSimpleMap()
24-
valueStore := smt.NewSimpleMap()
2525
// Initialise the tree
26-
tree := smt.NewSparseMerkleTree(nodeStore, valueStore, sha256.New())
26+
tree := smt.NewSMT(nodeStore, sha256.New())
2727

2828
// Update the key "foo" with the value "bar"
29-
_, _ = tree.Update([]byte("foo"), []byte("bar"))
29+
_ = tree.Update([]byte("foo"), []byte("bar"))
3030

3131
// Generate a Merkle proof for foo=bar
3232
proof, _ := tree.Prove([]byte("foo"))
3333
root := tree.Root() // We also need the current tree root for the proof
3434

3535
// Verify the Merkle proof for foo=bar
36-
if smt.VerifyProof(proof, root, []byte("foo"), []byte("bar"), sha256.New()) {
36+
if smt.VerifyProof(proof, root, []byte("foo"), []byte("bar"), tree.Spec()) {
3737
fmt.Println("Proof verification succeeded.")
3838
} else {
3939
fmt.Println("Proof verification failed.")

bench_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,29 @@ import (
88

99
func BenchmarkSparseMerkleTree_Update(b *testing.B) {
1010
smn, smv := NewSimpleMap(), NewSimpleMap()
11-
smt := NewSparseMerkleTree(smn, smv, sha256.New())
11+
smt := NewSMTWithStorage(smn, smv, sha256.New())
1212

1313
b.ResetTimer()
1414
b.ReportAllocs()
1515
for i := 0; i < b.N; i++ {
1616
s := strconv.Itoa(i)
17-
_, _ = smt.Update([]byte(s), []byte(s))
17+
_ = smt.Update([]byte(s), []byte(s))
1818
}
1919
}
2020

2121
func BenchmarkSparseMerkleTree_Delete(b *testing.B) {
2222
smn, smv := NewSimpleMap(), NewSimpleMap()
23-
smt := NewSparseMerkleTree(smn, smv, sha256.New())
23+
smt := NewSMTWithStorage(smn, smv, sha256.New())
2424

2525
for i := 0; i < 100000; i++ {
2626
s := strconv.Itoa(i)
27-
_, _ = smt.Update([]byte(s), []byte(s))
27+
_ = smt.Update([]byte(s), []byte(s))
2828
}
2929

3030
b.ResetTimer()
3131
b.ReportAllocs()
3232
for i := 0; i < b.N; i++ {
3333
s := strconv.Itoa(i)
34-
_, _ = smt.Delete([]byte(s))
34+
_ = smt.Delete([]byte(s))
3535
}
3636
}

bulk_test.go

+53-54
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,36 @@ import (
44
"bytes"
55
"crypto/sha256"
66
"math/rand"
7-
"reflect"
87
"testing"
98
)
109

10+
type opCounts struct{ ops, inserts, updates, deletes int }
11+
type bulkop struct{ key, val []byte }
12+
1113
// Test all tree operations in bulk.
12-
func TestSparseMerkleTree(t *testing.T) {
13-
for i := 0; i < 5; i++ {
14+
func TestBulkOperations(t *testing.T) {
15+
rand.Seed(1)
16+
17+
cases := []opCounts{
1418
// Test more inserts/updates than deletions.
15-
bulkOperations(t, 200, 100, 100, 50)
16-
}
17-
for i := 0; i < 5; i++ {
19+
{200, 100, 100, 50},
20+
{1000, 100, 100, 50},
1821
// Test extreme deletions.
19-
bulkOperations(t, 200, 100, 100, 500)
22+
{200, 100, 100, 500},
23+
{1000, 100, 100, 500},
24+
}
25+
for _, tc := range cases {
26+
bulkOperations(t, tc.ops, tc.inserts, tc.updates, tc.deletes)
2027
}
2128
}
2229

2330
// Test all tree operations in bulk, with specified ratio probabilities of insert, update and delete.
2431
func bulkOperations(t *testing.T, operations int, insert int, update int, delete int) {
2532
smn, smv := NewSimpleMap(), NewSimpleMap()
26-
smt := NewSparseMerkleTree(smn, smv, sha256.New())
33+
smt := NewSMTWithStorage(smn, smv, sha256.New())
2734

2835
max := insert + update + delete
29-
kv := make(map[string]string)
36+
var kv []bulkop
3037

3138
for i := 0; i < operations; i++ {
3239
n := rand.Intn(max)
@@ -39,98 +46,90 @@ func bulkOperations(t *testing.T, operations int, insert int, update int, delete
3946
val := make([]byte, valLen)
4047
rand.Read(val)
4148

42-
kv[string(key)] = string(val)
43-
_, err := smt.Update(key, val)
49+
err := smt.Update(key, val)
4450
if err != nil {
45-
t.Errorf("error: %v", err)
51+
t.Fatalf("error: %v", err)
4652
}
53+
kv = append(kv, bulkop{key, val})
4754
} else if n > insert && n < insert+update { // Update
48-
keys := reflect.ValueOf(kv).MapKeys()
49-
if len(keys) == 0 {
55+
if len(kv) == 0 {
5056
continue
5157
}
52-
key := []byte(keys[rand.Intn(len(keys))].Interface().(string))
53-
58+
ki := rand.Intn(len(kv))
5459
valLen := 1 + rand.Intn(64)
5560
val := make([]byte, valLen)
5661
rand.Read(val)
5762

58-
kv[string(key)] = string(val)
59-
_, err := smt.Update(key, val)
63+
err := smt.Update(kv[ki].key, val)
6064
if err != nil {
61-
t.Errorf("error: %v", err)
65+
t.Fatalf("error: %v", err)
6266
}
67+
kv[ki].val = val
6368
} else { // Delete
64-
keys := reflect.ValueOf(kv).MapKeys()
65-
if len(keys) == 0 {
69+
if len(kv) == 0 {
6670
continue
6771
}
68-
key := []byte(keys[rand.Intn(len(keys))].Interface().(string))
72+
ki := rand.Intn(len(kv))
6973

70-
kv[string(key)] = ""
71-
_, err := smt.Update(key, defaultValue)
72-
if err != nil {
73-
t.Errorf("error: %v", err)
74+
err := smt.Delete(kv[ki].key)
75+
if err != nil && err != ErrKeyNotPresent {
76+
t.Fatalf("error: %v", err)
7477
}
78+
kv[ki].val = defaultValue
7579
}
76-
77-
bulkCheckAll(t, smt, &kv)
7880
}
81+
bulkCheckAll(t, smt, kv)
7982
}
8083

81-
func bulkCheckAll(t *testing.T, smt *SparseMerkleTree, kv *map[string]string) {
82-
for k, v := range *kv {
83-
value, err := smt.Get([]byte(k))
84+
func bulkCheckAll(t *testing.T, smt *SMTWithStorage, kv []bulkop) {
85+
for ki := range kv {
86+
k, v := kv[ki].key, kv[ki].val
87+
88+
value, err := smt.GetValue([]byte(k))
8489
if err != nil {
8590
t.Errorf("error: %v", err)
8691
}
8792
if !bytes.Equal([]byte(v), value) {
88-
t.Error("got incorrect value when bulk testing operations")
93+
t.Errorf("Incorrect value (i=%d)", ki)
8994
}
9095

9196
// Generate and verify a Merkle proof for this key.
9297
proof, err := smt.Prove([]byte(k))
9398
if err != nil {
9499
t.Errorf("error: %v", err)
95100
}
96-
if !VerifyProof(proof, smt.Root(), []byte(k), []byte(v), smt.th.hasher) {
97-
t.Error("Merkle proof failed to verify")
101+
if !VerifyProof(proof, smt.Root(), []byte(k), []byte(v), smt.Spec()) {
102+
t.Fatalf("Merkle proof failed to verify (i=%d): %v", ki, []byte(k))
98103
}
99-
compactProof, err := smt.ProveCompact([]byte(k))
104+
compactProof, err := ProveCompact([]byte(k), smt)
100105
if err != nil {
101106
t.Errorf("error: %v", err)
102107
}
103-
if !VerifyCompactProof(compactProof, smt.Root(), []byte(k), []byte(v), smt.th.hasher) {
104-
t.Error("Merkle proof failed to verify")
108+
if !VerifyCompactProof(compactProof, smt.Root(), []byte(k), []byte(v), smt.Spec()) {
109+
t.Fatalf("Compact Merkle proof failed to verify (i=%d): %v", ki, []byte(k))
105110
}
106111

107-
if v == "" {
112+
if v == nil {
108113
continue
109114
}
110115

111116
// Check that the key is at the correct height in the tree.
112117
largestCommonPrefix := 0
113-
for k2, v2 := range *kv {
114-
if v2 == "" {
118+
for ki2 := range kv {
119+
k2, v2 := kv[ki2].key, kv[ki2].val
120+
if v2 == nil {
115121
continue
116122
}
117-
commonPrefix := countCommonPrefix(smt.th.path([]byte(k)), smt.th.path([]byte(k2)))
118-
if commonPrefix != smt.depth() && commonPrefix > largestCommonPrefix {
123+
124+
ph := smt.Spec().ph
125+
commonPrefix := countCommonPrefix(ph.Path([]byte(k)), ph.Path([]byte(k2)), 0)
126+
if commonPrefix != smt.Spec().depth() && commonPrefix > largestCommonPrefix {
119127
largestCommonPrefix = commonPrefix
120128
}
121129
}
122-
sideNodes, _, _, _, err := smt.sideNodesForRoot(smt.th.path([]byte(k)), smt.Root(), false)
123-
if err != nil {
124-
t.Errorf("error: %v", err)
125-
}
126-
numSideNodes := 0
127-
for _, v := range sideNodes {
128-
if v != nil {
129-
numSideNodes++
130-
}
131-
}
132-
if numSideNodes != largestCommonPrefix+1 && (numSideNodes != 0 && largestCommonPrefix != 0) {
133-
t.Error("leaf is at unexpected height")
130+
if len(proof.SideNodes) != largestCommonPrefix+1 &&
131+
(len(proof.SideNodes) != 0 && largestCommonPrefix != 0) {
132+
t.Errorf("leaf is at unexpected height (ki=%d)", ki)
134133
}
135134
}
136135
}

deepsubtree.go

-129
This file was deleted.

0 commit comments

Comments
 (0)