@@ -32,58 +32,113 @@ func init() {
32
32
mrand .Seed (time .Now ().Unix ())
33
33
}
34
34
35
+ // makeProvers creates Merkle trie provers based on different implementations to
36
+ // test all variations.
37
+ func makeProvers (trie * Trie ) []func (key []byte ) * ethdb.MemDatabase {
38
+ var provers []func (key []byte ) * ethdb.MemDatabase
39
+
40
+ // Create a direct trie based Merkle prover
41
+ provers = append (provers , func (key []byte ) * ethdb.MemDatabase {
42
+ proof := ethdb .NewMemDatabase ()
43
+ trie .Prove (key , 0 , proof )
44
+ return proof
45
+ })
46
+ // Create a leaf iterator based Merkle prover
47
+ provers = append (provers , func (key []byte ) * ethdb.MemDatabase {
48
+ proof := ethdb .NewMemDatabase ()
49
+ if it := NewIterator (trie .NodeIterator (key )); it .Next () && bytes .Equal (key , it .Key ) {
50
+ for _ , p := range it .Prove () {
51
+ proof .Put (crypto .Keccak256 (p ), p )
52
+ }
53
+ }
54
+ return proof
55
+ })
56
+ return provers
57
+ }
58
+
35
59
func TestProof (t * testing.T ) {
36
60
trie , vals := randomTrie (500 )
37
61
root := trie .Hash ()
38
- for _ , kv := range vals {
39
- proofs := ethdb .NewMemDatabase ()
40
- if trie .Prove (kv .k , 0 , proofs ) != nil {
41
- t .Fatalf ("missing key %x while constructing proof" , kv .k )
42
- }
43
- val , _ , err := VerifyProof (root , kv .k , proofs )
44
- if err != nil {
45
- t .Fatalf ("VerifyProof error for key %x: %v\n raw proof: %v" , kv .k , err , proofs )
46
- }
47
- if ! bytes .Equal (val , kv .v ) {
48
- t .Fatalf ("VerifyProof returned wrong value for key %x: got %x, want %x" , kv .k , val , kv .v )
62
+ for i , prover := range makeProvers (trie ) {
63
+ for _ , kv := range vals {
64
+ proof := prover (kv .k )
65
+ if proof == nil {
66
+ t .Fatalf ("prover %d: missing key %x while constructing proof" , i , kv .k )
67
+ }
68
+ val , _ , err := VerifyProof (root , kv .k , proof )
69
+ if err != nil {
70
+ t .Fatalf ("prover %d: failed to verify proof for key %x: %v\n raw proof: %x" , i , kv .k , err , proof )
71
+ }
72
+ if ! bytes .Equal (val , kv .v ) {
73
+ t .Fatalf ("prover %d: verified value mismatch for key %x: have %x, want %x" , i , kv .k , val , kv .v )
74
+ }
49
75
}
50
76
}
51
77
}
52
78
53
79
func TestOneElementProof (t * testing.T ) {
54
80
trie := new (Trie )
55
81
updateString (trie , "k" , "v" )
56
- proofs := ethdb .NewMemDatabase ()
57
- trie .Prove ([]byte ("k" ), 0 , proofs )
58
- if len (proofs .Keys ()) != 1 {
59
- t .Error ("proof should have one element" )
60
- }
61
- val , _ , err := VerifyProof (trie .Hash (), []byte ("k" ), proofs )
62
- if err != nil {
63
- t .Fatalf ("VerifyProof error: %v\n proof hashes: %v" , err , proofs .Keys ())
64
- }
65
- if ! bytes .Equal (val , []byte ("v" )) {
66
- t .Fatalf ("VerifyProof returned wrong value: got %x, want 'k'" , val )
82
+ for i , prover := range makeProvers (trie ) {
83
+ proof := prover ([]byte ("k" ))
84
+ if proof == nil {
85
+ t .Fatalf ("prover %d: nil proof" , i )
86
+ }
87
+ if proof .Len () != 1 {
88
+ t .Errorf ("prover %d: proof should have one element" , i )
89
+ }
90
+ val , _ , err := VerifyProof (trie .Hash (), []byte ("k" ), proof )
91
+ if err != nil {
92
+ t .Fatalf ("prover %d: failed to verify proof: %v\n raw proof: %x" , i , err , proof )
93
+ }
94
+ if ! bytes .Equal (val , []byte ("v" )) {
95
+ t .Fatalf ("prover %d: verified value mismatch: have %x, want 'k'" , i , val )
96
+ }
67
97
}
68
98
}
69
99
70
- func TestVerifyBadProof (t * testing.T ) {
100
+ func TestBadProof (t * testing.T ) {
71
101
trie , vals := randomTrie (800 )
72
102
root := trie .Hash ()
73
- for _ , kv := range vals {
74
- proofs := ethdb .NewMemDatabase ()
75
- trie .Prove (kv .k , 0 , proofs )
76
- if len (proofs .Keys ()) == 0 {
77
- t .Fatal ("zero length proof" )
103
+ for i , prover := range makeProvers (trie ) {
104
+ for _ , kv := range vals {
105
+ proof := prover (kv .k )
106
+ if proof == nil {
107
+ t .Fatalf ("prover %d: nil proof" , i )
108
+ }
109
+ key := proof .Keys ()[mrand .Intn (proof .Len ())]
110
+ val , _ := proof .Get (key )
111
+ proof .Delete (key )
112
+
113
+ mutateByte (val )
114
+ proof .Put (crypto .Keccak256 (val ), val )
115
+
116
+ if _ , _ , err := VerifyProof (root , kv .k , proof ); err == nil {
117
+ t .Fatalf ("prover %d: expected proof to fail for key %x" , i , kv .k )
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ // Tests that missing keys can also be proven. The test explicitly uses a single
124
+ // entry trie and checks for missing keys both before and after the single entry.
125
+ func TestMissingKeyProof (t * testing.T ) {
126
+ trie := new (Trie )
127
+ updateString (trie , "k" , "v" )
128
+
129
+ for i , key := range []string {"a" , "j" , "l" , "z" } {
130
+ proof := ethdb .NewMemDatabase ()
131
+ trie .Prove ([]byte (key ), 0 , proof )
132
+
133
+ if proof .Len () != 1 {
134
+ t .Errorf ("test %d: proof should have one element" , i )
135
+ }
136
+ val , _ , err := VerifyProof (trie .Hash (), []byte (key ), proof )
137
+ if err != nil {
138
+ t .Fatalf ("test %d: failed to verify proof: %v\n raw proof: %x" , i , err , proof )
78
139
}
79
- keys := proofs .Keys ()
80
- key := keys [mrand .Intn (len (keys ))]
81
- node , _ := proofs .Get (key )
82
- proofs .Delete (key )
83
- mutateByte (node )
84
- proofs .Put (crypto .Keccak256 (node ), node )
85
- if _ , _ , err := VerifyProof (root , kv .k , proofs ); err == nil {
86
- t .Fatalf ("expected proof to fail for key %x" , kv .k )
140
+ if val != nil {
141
+ t .Fatalf ("test %d: verified value mismatch: have %x, want nil" , i , val )
87
142
}
88
143
}
89
144
}
0 commit comments