@@ -25,10 +25,11 @@ import (
25
25
"math/rand"
26
26
"reflect"
27
27
"strings"
28
+ "sync"
28
29
"testing"
29
30
"testing/quick"
30
31
31
- check "gopkg.in/check.v1"
32
+ "gopkg.in/check.v1"
32
33
33
34
"github.com/ethereum/go-ethereum/common"
34
35
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -53,8 +54,13 @@ func TestUpdateLeaks(t *testing.T) {
53
54
if i % 3 == 0 {
54
55
state .SetCode (addr , []byte {i , i , i , i , i })
55
56
}
56
- state .IntermediateRoot (false )
57
57
}
58
+
59
+ root := state .IntermediateRoot (false )
60
+ if err := state .Database ().TrieDB ().Commit (root , false ); err != nil {
61
+ t .Errorf ("can not commit trie %v to persistent database" , root .Hex ())
62
+ }
63
+
58
64
// Ensure that no data was leaked into the database
59
65
it := db .NewIterator ()
60
66
for it .Next () {
@@ -98,27 +104,45 @@ func TestIntermediateLeaks(t *testing.T) {
98
104
}
99
105
100
106
// Commit and cross check the databases.
101
- if _ , err := transState .Commit (false ); err != nil {
107
+ transRoot , err := transState .Commit (false )
108
+ if err != nil {
102
109
t .Fatalf ("failed to commit transition state: %v" , err )
103
110
}
104
- if _ , err := finalState .Commit (false ); err != nil {
111
+ if err = transState .Database ().TrieDB ().Commit (transRoot , false ); err != nil {
112
+ t .Errorf ("can not commit trie %v to persistent database" , transRoot .Hex ())
113
+ }
114
+
115
+ finalRoot , err := finalState .Commit (false )
116
+ if err != nil {
105
117
t .Fatalf ("failed to commit final state: %v" , err )
106
118
}
119
+ if err = finalState .Database ().TrieDB ().Commit (finalRoot , false ); err != nil {
120
+ t .Errorf ("can not commit trie %v to persistent database" , finalRoot .Hex ())
121
+ }
122
+
107
123
it := finalDb .NewIterator ()
108
124
for it .Next () {
109
- key := it .Key ()
110
- if _ , err := transDb .Get (key ); err != nil {
111
- t .Errorf ("entry missing from the transition database: %x -> %x" , key , it .Value ())
125
+ key , fvalue := it .Key (), it .Value ()
126
+ tvalue , err := transDb .Get (key )
127
+ if err != nil {
128
+ t .Errorf ("entry missing from the transition database: %x -> %x" , key , fvalue )
129
+ }
130
+ if ! bytes .Equal (fvalue , tvalue ) {
131
+ t .Errorf ("the value associate key %x is mismatch,: %x in transition database ,%x in final database" , key , tvalue , fvalue )
112
132
}
113
133
}
114
134
it .Release ()
115
135
116
136
it = transDb .NewIterator ()
117
137
for it .Next () {
118
- key := it .Key ()
119
- if _ , err := finalDb .Get (key ); err != nil {
138
+ key , tvalue := it .Key (), it .Value ()
139
+ fvalue , err := finalDb .Get (key )
140
+ if err != nil {
120
141
t .Errorf ("extra entry in the transition database: %x -> %x" , key , it .Value ())
121
142
}
143
+ if ! bytes .Equal (fvalue , tvalue ) {
144
+ t .Errorf ("the value associate key %x is mismatch,: %x in transition database ,%x in final database" , key , tvalue , fvalue )
145
+ }
122
146
}
123
147
}
124
148
@@ -136,39 +160,55 @@ func TestCopy(t *testing.T) {
136
160
}
137
161
orig .Finalise (false )
138
162
139
- // Copy the state, modify both in-memory
163
+ // Copy the state
140
164
copy := orig .Copy ()
141
165
166
+ // Copy the copy state
167
+ ccopy := copy .Copy ()
168
+
169
+ // modify all in memory
142
170
for i := byte (0 ); i < 255 ; i ++ {
143
171
origObj := orig .GetOrNewStateObject (common .BytesToAddress ([]byte {i }))
144
172
copyObj := copy .GetOrNewStateObject (common .BytesToAddress ([]byte {i }))
173
+ ccopyObj := ccopy .GetOrNewStateObject (common .BytesToAddress ([]byte {i }))
145
174
146
175
origObj .AddBalance (big .NewInt (2 * int64 (i )))
147
176
copyObj .AddBalance (big .NewInt (3 * int64 (i )))
177
+ ccopyObj .AddBalance (big .NewInt (4 * int64 (i )))
148
178
149
179
orig .updateStateObject (origObj )
150
180
copy .updateStateObject (copyObj )
181
+ ccopy .updateStateObject (copyObj )
151
182
}
152
- // Finalise the changes on both concurrently
153
- done := make (chan struct {})
154
- go func () {
155
- orig .Finalise (true )
156
- close (done )
157
- }()
158
- copy .Finalise (true )
159
- <- done
160
183
161
- // Verify that the two states have been updated independently
184
+ // Finalise the changes on all concurrently
185
+ finalise := func (wg * sync.WaitGroup , db * StateDB ) {
186
+ defer wg .Done ()
187
+ db .Finalise (true )
188
+ }
189
+
190
+ var wg sync.WaitGroup
191
+ wg .Add (3 )
192
+ go finalise (& wg , orig )
193
+ go finalise (& wg , copy )
194
+ go finalise (& wg , ccopy )
195
+ wg .Wait ()
196
+
197
+ // Verify that the three states have been updated independently
162
198
for i := byte (0 ); i < 255 ; i ++ {
163
199
origObj := orig .GetOrNewStateObject (common .BytesToAddress ([]byte {i }))
164
200
copyObj := copy .GetOrNewStateObject (common .BytesToAddress ([]byte {i }))
201
+ ccopyObj := ccopy .GetOrNewStateObject (common .BytesToAddress ([]byte {i }))
165
202
166
203
if want := big .NewInt (3 * int64 (i )); origObj .Balance ().Cmp (want ) != 0 {
167
204
t .Errorf ("orig obj %d: balance mismatch: have %v, want %v" , i , origObj .Balance (), want )
168
205
}
169
206
if want := big .NewInt (4 * int64 (i )); copyObj .Balance ().Cmp (want ) != 0 {
170
207
t .Errorf ("copy obj %d: balance mismatch: have %v, want %v" , i , copyObj .Balance (), want )
171
208
}
209
+ if want := big .NewInt (5 * int64 (i )); ccopyObj .Balance ().Cmp (want ) != 0 {
210
+ t .Errorf ("copy obj %d: balance mismatch: have %v, want %v" , i , ccopyObj .Balance (), want )
211
+ }
172
212
}
173
213
}
174
214
0 commit comments