-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathproof_test.go
84 lines (70 loc) · 2.44 KB
/
proof_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package main
import (
"fmt"
"testing"
"github.com/ethereum/go-ethereum/trie"
"github.com/stretchr/testify/require"
)
func TestEthProof(t *testing.T) {
mpt := new(trie.Trie)
mpt.Update([]byte{1, 2, 3}, []byte("hello"))
mpt.Update([]byte{1, 2, 3, 4, 5}, []byte("world"))
w := NewProofDB()
err := mpt.Prove([]byte{1, 2, 3}, 0, w)
require.NoError(t, err)
rootHash := mpt.Hash()
val, err := trie.VerifyProof(rootHash, []byte{1, 2, 3}, w)
require.NoError(t, err)
require.Equal(t, []byte("hello"), val)
fmt.Printf("root hash: %x\n", rootHash)
}
func TestMyTrie(t *testing.T) {
tr := NewTrie()
tr.Put([]byte{1, 2, 3}, []byte("hello"))
tr.Put([]byte{1, 2, 3, 4, 5}, []byte("world"))
n0, ok := tr.root.(*ExtensionNode)
require.True(t, ok)
n1, ok := n0.Next.(*BranchNode)
require.True(t, ok)
fmt.Printf("n0 hash: %x, Serialized: %x\n", n0.Hash(), n0.Serialize())
fmt.Printf("n1 hash: %x, Serialized: %x\n", n1.Hash(), n1.Serialize())
}
func TestProveAndVerifyProof(t *testing.T) {
t.Run("should not generate proof for non-exist key", func(t *testing.T) {
tr := NewTrie()
tr.Put([]byte{1, 2, 3}, []byte("hello"))
tr.Put([]byte{1, 2, 3, 4, 5}, []byte("world"))
notExistKey := []byte{1, 2, 3, 4}
_, ok := tr.Prove(notExistKey)
require.False(t, ok)
})
t.Run("should generate a proof for an existing key, the proof can be verified with the merkle root hash", func(t *testing.T) {
tr := NewTrie()
tr.Put([]byte{1, 2, 3}, []byte("hello"))
tr.Put([]byte{1, 2, 3, 4, 5}, []byte("world"))
key := []byte{1, 2, 3}
proof, ok := tr.Prove(key)
require.True(t, ok)
rootHash := tr.Hash()
// verify the proof with the root hash, the key in question and its proof
val, err := VerifyProof(rootHash, key, proof)
require.NoError(t, err)
// when the verification has passed, it should return the correct value for the key
require.Equal(t, []byte("hello"), val)
})
t.Run("should fail the verification of the trie was updated", func(t *testing.T) {
tr := NewTrie()
tr.Put([]byte{1, 2, 3}, []byte("hello"))
tr.Put([]byte{1, 2, 3, 4, 5}, []byte("world"))
// the hash was taken before the trie was updated
rootHash := tr.Hash()
// the proof was generated after the trie was updated
tr.Put([]byte{5, 6, 7}, []byte("trie"))
key := []byte{1, 2, 3}
proof, ok := tr.Prove(key)
require.True(t, ok)
// should fail the verification since the merkle root hash doesn't match
_, err := VerifyProof(rootHash, key, proof)
require.Error(t, err)
})
}