Skip to content

Commit 23aefe3

Browse files
rjl493456442holiman
authored andcommitted
core/state/snapshot: udpate tests
1 parent ef79890 commit 23aefe3

File tree

1 file changed

+132
-52
lines changed

1 file changed

+132
-52
lines changed

core/state/snapshot/generate_test.go

Lines changed: 132 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -187,42 +187,33 @@ func newHelper() *testHelper {
187187
}
188188
}
189189

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) {
192191
val, _ := rlp.EncodeToBytes(acc)
193-
// Add to trie
194-
t.accTrie.Update([]byte(accPreKey), val)
192+
t.accTrie.Update([]byte(acckey), val)
195193
}
196194

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) {
199196
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))
204198
rawdb.WriteAccountSnapshot(t.diskdb, key, val)
205199
}
206200

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)
214204
}
215205

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+
}
220211
}
221212

222-
func (t *testHelper) makeStorageTrie(keys []string, values []string) []byte {
213+
func (t *testHelper) makeStorageTrie(keys []string, vals []string) []byte {
223214
stTrie, _ := trie.NewSecure(common.Hash{}, t.triedb)
224215
for i, k := range keys {
225-
stTrie.Update([]byte(k), []byte(values[i]))
216+
stTrie.Update([]byte(k), []byte(vals[i]))
226217
}
227218
root, _ := stTrie.Commit(nil)
228219
return root.Bytes()
@@ -235,47 +226,136 @@ func (t *testHelper) Generate() (common.Hash, *diskLayer) {
235226
return root, snap
236227
}
237228

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:
240231
// - 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
241233
// - the contract(non-empty storage) misses some storage slots
234+
// - miss in the beginning
235+
// - miss in the middle
236+
// - miss in the end
242237
// - 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
243245
func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
244-
245246
helper := newHelper()
246247
stRoot := helper.makeStorageTrie([]string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
247248

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
251311

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+
}
255321

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+
}
261340

262-
// Account four has a modified codehash
341+
// Wrong accounts
263342
{
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()})
270348
}
271349

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+
}
276356

277357
root, snap := helper.Generate()
278-
t.Logf("Root: %#x\n", root) // Root: 0x3a97ece15e2539ab3524783c37ca153a62e28faba76a752e826da24a9020d44f
358+
t.Logf("Root: %#x\n", root) // Root = 0x825891472281463511e7ebcc7f109e4f9200c20fa384754e11fd605cd98464e8
279359

280360
select {
281361
case <-snap.genPending:
@@ -285,6 +365,7 @@ func TestGenerateExistentStateWithWrongStorage(t *testing.T) {
285365
t.Errorf("Snapshot generation failed")
286366
}
287367
checkSnapRoot(t, snap, root)
368+
288369
// Signal abortion to the generator and wait for it to tear down
289370
stop := make(chan *generatorStats)
290371
snap.genAbort <- stop
@@ -466,7 +547,6 @@ func getStorageTrie(n int, triedb *trie.Database) *trie.SecureTrie {
466547

467548
// Tests that snapshot generation when an extra account with storage exists in the snap state.
468549
func TestGenerateWithExtraAccounts(t *testing.T) {
469-
470550
var (
471551
diskdb = memorydb.New()
472552
triedb = trie.NewDatabase(diskdb)
@@ -685,7 +765,7 @@ func TestGenerateFromEmptySnap(t *testing.T) {
685765
&Account{Balance: big.NewInt(1), Root: stRoot, CodeHash: emptyCode.Bytes()})
686766
}
687767
root, snap := helper.Generate()
688-
t.Logf("Root: %#x\n", root) // Root: 0x3a97ece15e2539ab3524783c37ca153a62e28faba76a752e826da24a9020d44f
768+
t.Logf("Root: %#x\n", root) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4
689769

690770
select {
691771
case <-snap.genPending:
@@ -732,7 +812,7 @@ func TestGenerateWithIncompleteStorage(t *testing.T) {
732812
}
733813

734814
root, snap := helper.Generate()
735-
t.Logf("Root: %#x\n", root) // Root: 0x3a97ece15e2539ab3524783c37ca153a62e28faba76a752e826da24a9020d44f
815+
t.Logf("Root: %#x\n", root) // Root: 0xca73f6f05ba4ca3024ef340ef3dfca8fdabc1b677ff13f5a9571fd49c16e67ff
736816

737817
select {
738818
case <-snap.genPending:

0 commit comments

Comments
 (0)