@@ -187,42 +187,33 @@ func newHelper() *testHelper {
187
187
}
188
188
}
189
189
190
- // addAccount adds an account to the trie and snapshot, and return t
191
- func (t * testHelper ) addTrieAccount (accPreKey string , acc * Account ) {
190
+ func (t * testHelper ) addTrieAccount (acckey string , acc * Account ) {
192
191
val , _ := rlp .EncodeToBytes (acc )
193
- // Add to trie
194
- t .accTrie .Update ([]byte (accPreKey ), val )
192
+ t .accTrie .Update ([]byte (acckey ), val )
195
193
}
196
194
197
- // addAccount adds an account to the trie and snapshot, and return t
198
- func (t * testHelper ) addAccount (accPreKey string , acc * Account ) {
195
+ func (t * testHelper ) addSnapAccount (acckey string , acc * Account ) {
199
196
val , _ := rlp .EncodeToBytes (acc )
200
- // Add to trie
201
- t .accTrie .Update ([]byte (accPreKey ), val )
202
- key := hashData ([]byte (accPreKey ))
203
- // Add account to snapshot
197
+ key := hashData ([]byte (acckey ))
204
198
rawdb .WriteAccountSnapshot (t .diskdb , key , val )
205
199
}
206
200
207
- func (t * testHelper ) addSnapStorage (accPreKey string , slotKeys []string , slotVals []string ) {
208
- key := hashData ([]byte (accPreKey ))
209
- // Add any storage slots
210
- for i , sKey := range slotKeys {
211
- sVal := []byte (slotVals [i ])
212
- rawdb .WriteStorageSnapshot (t .diskdb , key , hashData ([]byte (sKey )), sVal )
213
- }
201
+ func (t * testHelper ) addAccount (acckey string , acc * Account ) {
202
+ t .addTrieAccount (acckey , acc )
203
+ t .addSnapAccount (acckey , acc )
214
204
}
215
205
216
- func (t * testHelper ) writeSnapAccount (accPreKey string , acc * Account ) {
217
- val , _ := rlp .EncodeToBytes (acc )
218
- key := hashData ([]byte (accPreKey ))
219
- rawdb .WriteAccountSnapshot (t .diskdb , key , val )
206
+ func (t * testHelper ) addSnapStorage (accKey string , keys []string , vals []string ) {
207
+ accHash := hashData ([]byte (accKey ))
208
+ for i , key := range keys {
209
+ rawdb .WriteStorageSnapshot (t .diskdb , accHash , hashData ([]byte (key )), []byte (vals [i ]))
210
+ }
220
211
}
221
212
222
- func (t * testHelper ) makeStorageTrie (keys []string , values []string ) []byte {
213
+ func (t * testHelper ) makeStorageTrie (keys []string , vals []string ) []byte {
223
214
stTrie , _ := trie .NewSecure (common.Hash {}, t .triedb )
224
215
for i , k := range keys {
225
- stTrie .Update ([]byte (k ), []byte (values [i ]))
216
+ stTrie .Update ([]byte (k ), []byte (vals [i ]))
226
217
}
227
218
root , _ := stTrie .Commit (nil )
228
219
return root .Bytes ()
@@ -235,47 +226,136 @@ func (t *testHelper) Generate() (common.Hash, *diskLayer) {
235
226
return root , snap
236
227
}
237
228
238
- // Tests that snapshot generation with existent flat state, where the flat state contains
239
- // some errors:
229
+ // Tests that snapshot generation with existent flat state, where the flat state
230
+ // contains some errors:
240
231
// - the contract with empty storage root but has storage entries in the disk
232
+ // - the contract with non empty storage root but empty storage slots
241
233
// - the contract(non-empty storage) misses some storage slots
234
+ // - miss in the beginning
235
+ // - miss in the middle
236
+ // - miss in the end
242
237
// - the contract(non-empty storage) has wrong storage slots
238
+ // - wrong slots in the beginning
239
+ // - wrong slots in the middle
240
+ // - wrong slots in the end
241
+ // - the contract(non-empty storage) has extra storage slots
242
+ // - extra slots in the beginning
243
+ // - extra slots in the middle
244
+ // - extra slots in the end
243
245
func TestGenerateExistentStateWithWrongStorage (t * testing.T ) {
244
-
245
246
helper := newHelper ()
246
247
stRoot := helper .makeStorageTrie ([]string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "val-2" , "val-3" })
247
248
248
- // Account one, miss storage slots in the end(key-3)
249
- helper .addAccount ("acc-1" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
250
- helper .addSnapStorage ("acc-1" , []string {"key-1" , "key-2" }, []string {"val-1" , "val-2" })
249
+ // Account one, empty root but non-empty database
250
+ helper .addAccount ("acc-1" , & Account {Balance : big .NewInt (1 ), Root : emptyRoot .Bytes (), CodeHash : emptyCode .Bytes ()})
251
+ helper .addSnapStorage ("acc-1" , []string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "val-2" , "val-3" })
252
+
253
+ // Account two, non empty root but empty database
254
+ helper .addAccount ("acc-2" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
255
+
256
+ // Miss slots
257
+ {
258
+ // Account three, non empty root but misses slots in the beginning
259
+ helper .addAccount ("acc-3" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
260
+ helper .addSnapStorage ("acc-3" , []string {"key-2" , "key-3" }, []string {"val-2" , "val-3" })
261
+
262
+ // Account four, non empty root but misses slots in the middle
263
+ helper .addAccount ("acc-4" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
264
+ helper .addSnapStorage ("acc-4" , []string {"key-1" , "key-3" }, []string {"val-1" , "val-3" })
265
+
266
+ // Account five, non empty root but misses slots in the end
267
+ helper .addAccount ("acc-5" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
268
+ helper .addSnapStorage ("acc-5" , []string {"key-1" , "key-2" }, []string {"val-1" , "val-2" })
269
+ }
270
+
271
+ // Wrong storage slots
272
+ {
273
+ // Account six, non empty root but wrong slots in the beginning
274
+ helper .addAccount ("acc-6" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
275
+ helper .addSnapStorage ("acc-6" , []string {"key-1" , "key-2" , "key-3" }, []string {"badval-1" , "val-2" , "val-3" })
276
+
277
+ // Account seven, non empty root but wrong slots in the middle
278
+ helper .addAccount ("acc-7" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
279
+ helper .addSnapStorage ("acc-7" , []string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "badval-2" , "val-3" })
280
+
281
+ // Account eight, non empty root but wrong slots in the end
282
+ helper .addAccount ("acc-8" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
283
+ helper .addSnapStorage ("acc-8" , []string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "val-2" , "badval-3" })
284
+
285
+ // Account 9, non empty root but rotated slots
286
+ helper .addAccount ("acc-9" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
287
+ helper .addSnapStorage ("acc-9" , []string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "val-3" , "val-2" })
288
+ }
289
+
290
+ // Extra storage slots
291
+ {
292
+ // Account 10, non empty root but extra slots in the beginning
293
+ helper .addAccount ("acc-10" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
294
+ helper .addSnapStorage ("acc-10" , []string {"key-0" , "key-1" , "key-2" , "key-3" }, []string {"val-0" , "val-1" , "val-2" , "val-3" })
295
+
296
+ // Account 11, non empty root but extra slots in the middle
297
+ helper .addAccount ("acc-11" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
298
+ helper .addSnapStorage ("acc-11" , []string {"key-1" , "key-2" , "key-2-1" , "key-3" }, []string {"val-1" , "val-2" , "val-2-1" , "val-3" })
299
+
300
+ // Account 12, non empty root but extra slots in the end
301
+ helper .addAccount ("acc-12" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
302
+ helper .addSnapStorage ("acc-12" , []string {"key-1" , "key-2" , "key-3" , "key-4" }, []string {"val-1" , "val-2" , "val-3" , "val-4" })
303
+ }
304
+
305
+ root , snap := helper .Generate ()
306
+ t .Logf ("Root: %#x\n " , root ) // Root = 0x8746cce9fd9c658b2cfd639878ed6584b7a2b3e73bb40f607fcfa156002429a0
307
+
308
+ select {
309
+ case <- snap .genPending :
310
+ // Snapshot generation succeeded
251
311
252
- // Account two, miss storage slots in the beginning(key-1)
253
- helper .addAccount ("acc-2" , & Account {Balance : big .NewInt (2 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
254
- helper .addSnapStorage ("acc-2" , []string {"key-2" , "key-3" }, []string {"val-2" , "val-3" })
312
+ case <- time .After (250 * time .Millisecond ):
313
+ t .Errorf ("Snapshot generation failed" )
314
+ }
315
+ checkSnapRoot (t , snap , root )
316
+ // Signal abortion to the generator and wait for it to tear down
317
+ stop := make (chan * generatorStats )
318
+ snap .genAbort <- stop
319
+ <- stop
320
+ }
255
321
256
- // Account three
257
- // The storage root is emptyHash, but the flat db has some storage values. This can happen
258
- // if the storage was unset during sync
259
- helper .addAccount ("acc-3" , & Account {Balance : big .NewInt (2 ), Root : emptyRoot .Bytes (), CodeHash : emptyCode .Bytes ()})
260
- helper .addSnapStorage ("acc-3" , []string {"key-1" }, []string {"val-1" })
322
+ // Tests that snapshot generation with existent flat state, where the flat state
323
+ // contains some errors:
324
+ // - miss accounts
325
+ // - wrong accounts
326
+ // - extra accounts
327
+ func TestGenerateExistentStateWithWrongAccounts (t * testing.T ) {
328
+ helper := newHelper ()
329
+ stRoot := helper .makeStorageTrie ([]string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "val-2" , "val-3" })
330
+
331
+ // Trie accounts [acc-1, acc-2, acc-3, acc-4, acc-6]
332
+ // Extra accounts [acc-0, acc-5, acc-7]
333
+
334
+ // Missing accounts, only in the trie
335
+ {
336
+ helper .addTrieAccount ("acc-1" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()}) // Beginning
337
+ helper .addTrieAccount ("acc-4" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()}) // Middle
338
+ helper .addTrieAccount ("acc-6" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()}) // End
339
+ }
261
340
262
- // Account four has a modified codehash
341
+ // Wrong accounts
263
342
{
264
- acc := & Account {Balance : big .NewInt (3 ), Root : stRoot , CodeHash : emptyCode .Bytes ()}
265
- helper .addAccount ("acc-4" , acc )
266
- helper .addSnapStorage ("acc-4" , []string {"key-1" , "key-2" , "key-3" }, []string {"val-1" , "val-2" , "val-3" })
267
- // Overwrite the codehash in the snapdata
268
- acc .CodeHash = hashData ([]byte ("codez" )).Bytes ()
269
- helper .writeSnapAccount ("acc-4" , acc )
343
+ helper .addTrieAccount ("acc-2" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
344
+ helper .addSnapAccount ("acc-2" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : common .Hex2Bytes ("0x1234" )})
345
+
346
+ helper .addTrieAccount ("acc-3" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
347
+ helper .addSnapAccount ("acc-3" , & Account {Balance : big .NewInt (1 ), Root : emptyRoot .Bytes (), CodeHash : emptyCode .Bytes ()})
270
348
}
271
349
272
- // Account 5 has wrong storage slot values - they've been rotated.
273
- // This test that the update-or-replace check works
274
- helper .addAccount ("acc-5" , & Account {Balance : big .NewInt (3 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
275
- helper .addSnapStorage ("acc-5" , []string {"key-1" , "key-2" , "key-3" }, []string {"val-2" , "val-3" , "val-1" })
350
+ // Extra accounts, only in the snap
351
+ {
352
+ helper .addSnapAccount ("acc-0" , & Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyRoot .Bytes ()}) // before the beginning
353
+ helper .addSnapAccount ("acc-5" , & Account {Balance : big .NewInt (1 ), Root : emptyRoot .Bytes (), CodeHash : common .Hex2Bytes ("0x1234" )}) // Middle
354
+ helper .addSnapAccount ("acc-7" , & Account {Balance : big .NewInt (1 ), Root : emptyRoot .Bytes (), CodeHash : emptyRoot .Bytes ()}) // after the end
355
+ }
276
356
277
357
root , snap := helper .Generate ()
278
- t .Logf ("Root: %#x\n " , root ) // Root: 0x3a97ece15e2539ab3524783c37ca153a62e28faba76a752e826da24a9020d44f
358
+ t .Logf ("Root: %#x\n " , root ) // Root = 0x825891472281463511e7ebcc7f109e4f9200c20fa384754e11fd605cd98464e8
279
359
280
360
select {
281
361
case <- snap .genPending :
@@ -285,6 +365,7 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
285
365
t .Errorf ("Snapshot generation failed" )
286
366
}
287
367
checkSnapRoot (t , snap , root )
368
+
288
369
// Signal abortion to the generator and wait for it to tear down
289
370
stop := make (chan * generatorStats )
290
371
snap .genAbort <- stop
@@ -466,7 +547,6 @@ func getStorageTrie(n int, triedb *trie.Database) *trie.SecureTrie {
466
547
467
548
// Tests that snapshot generation when an extra account with storage exists in the snap state.
468
549
func TestGenerateWithExtraAccounts (t * testing.T ) {
469
-
470
550
var (
471
551
diskdb = memorydb .New ()
472
552
triedb = trie .NewDatabase (diskdb )
@@ -685,7 +765,7 @@ func TestGenerateFromEmptySnap(t *testing.T) {
685
765
& Account {Balance : big .NewInt (1 ), Root : stRoot , CodeHash : emptyCode .Bytes ()})
686
766
}
687
767
root , snap := helper .Generate ()
688
- t .Logf ("Root: %#x\n " , root ) // Root: 0x3a97ece15e2539ab3524783c37ca153a62e28faba76a752e826da24a9020d44f
768
+ t .Logf ("Root: %#x\n " , root ) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4
689
769
690
770
select {
691
771
case <- snap .genPending :
@@ -732,7 +812,7 @@ func TestGenerateWithIncompleteStorage(t *testing.T) {
732
812
}
733
813
734
814
root , snap := helper .Generate ()
735
- t .Logf ("Root: %#x\n " , root ) // Root: 0x3a97ece15e2539ab3524783c37ca153a62e28faba76a752e826da24a9020d44f
815
+ t .Logf ("Root: %#x\n " , root ) // Root: 0xca73f6f05ba4ca3024ef340ef3dfca8fdabc1b677ff13f5a9571fd49c16e67ff
736
816
737
817
select {
738
818
case <- snap .genPending :
0 commit comments