github.com/theQRL/go-zond@v0.1.1/core/state/snapshot/iterator_test.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package snapshot 18 19 import ( 20 "bytes" 21 crand "crypto/rand" 22 "encoding/binary" 23 "fmt" 24 "math/rand" 25 "testing" 26 27 "github.com/VictoriaMetrics/fastcache" 28 "github.com/theQRL/go-zond/common" 29 "github.com/theQRL/go-zond/core/rawdb" 30 ) 31 32 // TestAccountIteratorBasics tests some simple single-layer(diff and disk) iteration 33 func TestAccountIteratorBasics(t *testing.T) { 34 var ( 35 destructs = make(map[common.Hash]struct{}) 36 accounts = make(map[common.Hash][]byte) 37 storage = make(map[common.Hash]map[common.Hash][]byte) 38 ) 39 // Fill up a parent 40 for i := 0; i < 100; i++ { 41 h := randomHash() 42 data := randomAccount() 43 44 accounts[h] = data 45 if rand.Intn(4) == 0 { 46 destructs[h] = struct{}{} 47 } 48 if rand.Intn(2) == 0 { 49 accStorage := make(map[common.Hash][]byte) 50 value := make([]byte, 32) 51 crand.Read(value) 52 accStorage[randomHash()] = value 53 storage[h] = accStorage 54 } 55 } 56 // Add some (identical) layers on top 57 diffLayer := newDiffLayer(emptyLayer(), common.Hash{}, copyDestructs(destructs), copyAccounts(accounts), copyStorage(storage)) 58 it := diffLayer.AccountIterator(common.Hash{}) 59 verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator 60 61 diskLayer := diffToDisk(diffLayer) 62 it = diskLayer.AccountIterator(common.Hash{}) 63 verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator 64 } 65 66 // TestStorageIteratorBasics tests some simple single-layer(diff and disk) iteration for storage 67 func TestStorageIteratorBasics(t *testing.T) { 68 var ( 69 nilStorage = make(map[common.Hash]int) 70 accounts = make(map[common.Hash][]byte) 71 storage = make(map[common.Hash]map[common.Hash][]byte) 72 ) 73 // Fill some random data 74 for i := 0; i < 10; i++ { 75 h := randomHash() 76 accounts[h] = randomAccount() 77 78 accStorage := make(map[common.Hash][]byte) 79 value := make([]byte, 32) 80 81 var nilstorage int 82 for i := 0; i < 100; i++ { 83 crand.Read(value) 84 if rand.Intn(2) == 0 { 85 accStorage[randomHash()] = common.CopyBytes(value) 86 } else { 87 accStorage[randomHash()] = nil // delete slot 88 nilstorage += 1 89 } 90 } 91 storage[h] = accStorage 92 nilStorage[h] = nilstorage 93 } 94 // Add some (identical) layers on top 95 diffLayer := newDiffLayer(emptyLayer(), common.Hash{}, nil, copyAccounts(accounts), copyStorage(storage)) 96 for account := range accounts { 97 it, _ := diffLayer.StorageIterator(account, common.Hash{}) 98 verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator 99 } 100 101 diskLayer := diffToDisk(diffLayer) 102 for account := range accounts { 103 it, _ := diskLayer.StorageIterator(account, common.Hash{}) 104 verifyIterator(t, 100-nilStorage[account], it, verifyNothing) // Nil is allowed for single layer iterator 105 } 106 } 107 108 type testIterator struct { 109 values []byte 110 } 111 112 func newTestIterator(values ...byte) *testIterator { 113 return &testIterator{values} 114 } 115 116 func (ti *testIterator) Seek(common.Hash) { 117 panic("implement me") 118 } 119 120 func (ti *testIterator) Next() bool { 121 ti.values = ti.values[1:] 122 return len(ti.values) > 0 123 } 124 125 func (ti *testIterator) Error() error { 126 return nil 127 } 128 129 func (ti *testIterator) Hash() common.Hash { 130 return common.BytesToHash([]byte{ti.values[0]}) 131 } 132 133 func (ti *testIterator) Account() []byte { 134 return nil 135 } 136 137 func (ti *testIterator) Slot() []byte { 138 return nil 139 } 140 141 func (ti *testIterator) Release() {} 142 143 func TestFastIteratorBasics(t *testing.T) { 144 type testCase struct { 145 lists [][]byte 146 expKeys []byte 147 } 148 for i, tc := range []testCase{ 149 {lists: [][]byte{{0, 1, 8}, {1, 2, 8}, {2, 9}, {4}, 150 {7, 14, 15}, {9, 13, 15, 16}}, 151 expKeys: []byte{0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16}}, 152 {lists: [][]byte{{0, 8}, {1, 2, 8}, {7, 14, 15}, {8, 9}, 153 {9, 10}, {10, 13, 15, 16}}, 154 expKeys: []byte{0, 1, 2, 7, 8, 9, 10, 13, 14, 15, 16}}, 155 } { 156 var iterators []*weightedIterator 157 for i, data := range tc.lists { 158 it := newTestIterator(data...) 159 iterators = append(iterators, &weightedIterator{it, i}) 160 } 161 fi := &fastIterator{ 162 iterators: iterators, 163 initiated: false, 164 } 165 count := 0 166 for fi.Next() { 167 if got, exp := fi.Hash()[31], tc.expKeys[count]; exp != got { 168 t.Errorf("tc %d, [%d]: got %d exp %d", i, count, got, exp) 169 } 170 count++ 171 } 172 } 173 } 174 175 type verifyContent int 176 177 const ( 178 verifyNothing verifyContent = iota 179 verifyAccount 180 verifyStorage 181 ) 182 183 func verifyIterator(t *testing.T, expCount int, it Iterator, verify verifyContent) { 184 t.Helper() 185 186 var ( 187 count = 0 188 last = common.Hash{} 189 ) 190 for it.Next() { 191 hash := it.Hash() 192 if bytes.Compare(last[:], hash[:]) >= 0 { 193 t.Errorf("wrong order: %x >= %x", last, hash) 194 } 195 count++ 196 if verify == verifyAccount && len(it.(AccountIterator).Account()) == 0 { 197 t.Errorf("iterator returned nil-value for hash %x", hash) 198 } else if verify == verifyStorage && len(it.(StorageIterator).Slot()) == 0 { 199 t.Errorf("iterator returned nil-value for hash %x", hash) 200 } 201 last = hash 202 } 203 if count != expCount { 204 t.Errorf("iterator count mismatch: have %d, want %d", count, expCount) 205 } 206 if err := it.Error(); err != nil { 207 t.Errorf("iterator failed: %v", err) 208 } 209 } 210 211 // TestAccountIteratorTraversal tests some simple multi-layer iteration. 212 func TestAccountIteratorTraversal(t *testing.T) { 213 // Create an empty base layer and a snapshot tree out of it 214 base := &diskLayer{ 215 diskdb: rawdb.NewMemoryDatabase(), 216 root: common.HexToHash("0x01"), 217 cache: fastcache.New(1024 * 500), 218 } 219 snaps := &Tree{ 220 layers: map[common.Hash]snapshot{ 221 base.root: base, 222 }, 223 } 224 // Stack three diff layers on top with various overlaps 225 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, 226 randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil) 227 228 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, 229 randomAccountSet("0xbb", "0xdd", "0xf0"), nil) 230 231 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, 232 randomAccountSet("0xcc", "0xf0", "0xff"), nil) 233 234 // Verify the single and multi-layer iterators 235 head := snaps.Snapshot(common.HexToHash("0x04")) 236 237 verifyIterator(t, 3, head.(snapshot).AccountIterator(common.Hash{}), verifyNothing) 238 verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) 239 240 it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{}) 241 verifyIterator(t, 7, it, verifyAccount) 242 it.Release() 243 244 // Test after persist some bottom-most layers into the disk, 245 // the functionalities still work. 246 limit := aggregatorMemoryLimit 247 defer func() { 248 aggregatorMemoryLimit = limit 249 }() 250 aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk 251 snaps.Cap(common.HexToHash("0x04"), 2) 252 verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) 253 254 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{}) 255 verifyIterator(t, 7, it, verifyAccount) 256 it.Release() 257 } 258 259 func TestStorageIteratorTraversal(t *testing.T) { 260 // Create an empty base layer and a snapshot tree out of it 261 base := &diskLayer{ 262 diskdb: rawdb.NewMemoryDatabase(), 263 root: common.HexToHash("0x01"), 264 cache: fastcache.New(1024 * 500), 265 } 266 snaps := &Tree{ 267 layers: map[common.Hash]snapshot{ 268 base.root: base, 269 }, 270 } 271 // Stack three diff layers on top with various overlaps 272 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, 273 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil)) 274 275 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, 276 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil)) 277 278 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, 279 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil)) 280 281 // Verify the single and multi-layer iterators 282 head := snaps.Snapshot(common.HexToHash("0x04")) 283 284 diffIter, _ := head.(snapshot).StorageIterator(common.HexToHash("0xaa"), common.Hash{}) 285 verifyIterator(t, 3, diffIter, verifyNothing) 286 verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) 287 288 it, _ := snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) 289 verifyIterator(t, 6, it, verifyStorage) 290 it.Release() 291 292 // Test after persist some bottom-most layers into the disk, 293 // the functionalities still work. 294 limit := aggregatorMemoryLimit 295 defer func() { 296 aggregatorMemoryLimit = limit 297 }() 298 aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk 299 snaps.Cap(common.HexToHash("0x04"), 2) 300 verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) 301 302 it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) 303 verifyIterator(t, 6, it, verifyStorage) 304 it.Release() 305 } 306 307 // TestAccountIteratorTraversalValues tests some multi-layer iteration, where we 308 // also expect the correct values to show up. 309 func TestAccountIteratorTraversalValues(t *testing.T) { 310 // Create an empty base layer and a snapshot tree out of it 311 base := &diskLayer{ 312 diskdb: rawdb.NewMemoryDatabase(), 313 root: common.HexToHash("0x01"), 314 cache: fastcache.New(1024 * 500), 315 } 316 snaps := &Tree{ 317 layers: map[common.Hash]snapshot{ 318 base.root: base, 319 }, 320 } 321 // Create a batch of account sets to seed subsequent layers with 322 var ( 323 a = make(map[common.Hash][]byte) 324 b = make(map[common.Hash][]byte) 325 c = make(map[common.Hash][]byte) 326 d = make(map[common.Hash][]byte) 327 e = make(map[common.Hash][]byte) 328 f = make(map[common.Hash][]byte) 329 g = make(map[common.Hash][]byte) 330 h = make(map[common.Hash][]byte) 331 ) 332 for i := byte(2); i < 0xff; i++ { 333 a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) 334 if i > 20 && i%2 == 0 { 335 b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) 336 } 337 if i%4 == 0 { 338 c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) 339 } 340 if i%7 == 0 { 341 d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) 342 } 343 if i%8 == 0 { 344 e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) 345 } 346 if i > 50 || i < 85 { 347 f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) 348 } 349 if i%64 == 0 { 350 g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) 351 } 352 if i%128 == 0 { 353 h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) 354 } 355 } 356 // Assemble a stack of snapshots from the account layers 357 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, a, nil) 358 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, b, nil) 359 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, c, nil) 360 snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), nil, d, nil) 361 snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), nil, e, nil) 362 snaps.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), nil, f, nil) 363 snaps.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), nil, g, nil) 364 snaps.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), nil, h, nil) 365 366 it, _ := snaps.AccountIterator(common.HexToHash("0x09"), common.Hash{}) 367 head := snaps.Snapshot(common.HexToHash("0x09")) 368 for it.Next() { 369 hash := it.Hash() 370 want, err := head.AccountRLP(hash) 371 if err != nil { 372 t.Fatalf("failed to retrieve expected account: %v", err) 373 } 374 if have := it.Account(); !bytes.Equal(want, have) { 375 t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) 376 } 377 } 378 it.Release() 379 380 // Test after persist some bottom-most layers into the disk, 381 // the functionalities still work. 382 limit := aggregatorMemoryLimit 383 defer func() { 384 aggregatorMemoryLimit = limit 385 }() 386 aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk 387 snaps.Cap(common.HexToHash("0x09"), 2) 388 389 it, _ = snaps.AccountIterator(common.HexToHash("0x09"), common.Hash{}) 390 for it.Next() { 391 hash := it.Hash() 392 want, err := head.AccountRLP(hash) 393 if err != nil { 394 t.Fatalf("failed to retrieve expected account: %v", err) 395 } 396 if have := it.Account(); !bytes.Equal(want, have) { 397 t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want) 398 } 399 } 400 it.Release() 401 } 402 403 func TestStorageIteratorTraversalValues(t *testing.T) { 404 // Create an empty base layer and a snapshot tree out of it 405 base := &diskLayer{ 406 diskdb: rawdb.NewMemoryDatabase(), 407 root: common.HexToHash("0x01"), 408 cache: fastcache.New(1024 * 500), 409 } 410 snaps := &Tree{ 411 layers: map[common.Hash]snapshot{ 412 base.root: base, 413 }, 414 } 415 wrapStorage := func(storage map[common.Hash][]byte) map[common.Hash]map[common.Hash][]byte { 416 return map[common.Hash]map[common.Hash][]byte{ 417 common.HexToHash("0xaa"): storage, 418 } 419 } 420 // Create a batch of storage sets to seed subsequent layers with 421 var ( 422 a = make(map[common.Hash][]byte) 423 b = make(map[common.Hash][]byte) 424 c = make(map[common.Hash][]byte) 425 d = make(map[common.Hash][]byte) 426 e = make(map[common.Hash][]byte) 427 f = make(map[common.Hash][]byte) 428 g = make(map[common.Hash][]byte) 429 h = make(map[common.Hash][]byte) 430 ) 431 for i := byte(2); i < 0xff; i++ { 432 a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i)) 433 if i > 20 && i%2 == 0 { 434 b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i)) 435 } 436 if i%4 == 0 { 437 c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i)) 438 } 439 if i%7 == 0 { 440 d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i)) 441 } 442 if i%8 == 0 { 443 e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i)) 444 } 445 if i > 50 || i < 85 { 446 f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i)) 447 } 448 if i%64 == 0 { 449 g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i)) 450 } 451 if i%128 == 0 { 452 h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i)) 453 } 454 } 455 // Assemble a stack of snapshots from the account layers 456 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), wrapStorage(a)) 457 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), wrapStorage(b)) 458 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, randomAccountSet("0xaa"), wrapStorage(c)) 459 snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), nil, randomAccountSet("0xaa"), wrapStorage(d)) 460 snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), nil, randomAccountSet("0xaa"), wrapStorage(e)) 461 snaps.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), nil, randomAccountSet("0xaa"), wrapStorage(e)) 462 snaps.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), nil, randomAccountSet("0xaa"), wrapStorage(g)) 463 snaps.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), nil, randomAccountSet("0xaa"), wrapStorage(h)) 464 465 it, _ := snaps.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{}) 466 head := snaps.Snapshot(common.HexToHash("0x09")) 467 for it.Next() { 468 hash := it.Hash() 469 want, err := head.Storage(common.HexToHash("0xaa"), hash) 470 if err != nil { 471 t.Fatalf("failed to retrieve expected storage slot: %v", err) 472 } 473 if have := it.Slot(); !bytes.Equal(want, have) { 474 t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want) 475 } 476 } 477 it.Release() 478 479 // Test after persist some bottom-most layers into the disk, 480 // the functionalities still work. 481 limit := aggregatorMemoryLimit 482 defer func() { 483 aggregatorMemoryLimit = limit 484 }() 485 aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk 486 snaps.Cap(common.HexToHash("0x09"), 2) 487 488 it, _ = snaps.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{}) 489 for it.Next() { 490 hash := it.Hash() 491 want, err := head.Storage(common.HexToHash("0xaa"), hash) 492 if err != nil { 493 t.Fatalf("failed to retrieve expected slot: %v", err) 494 } 495 if have := it.Slot(); !bytes.Equal(want, have) { 496 t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want) 497 } 498 } 499 it.Release() 500 } 501 502 // This testcase is notorious, all layers contain the exact same 200 accounts. 503 func TestAccountIteratorLargeTraversal(t *testing.T) { 504 // Create a custom account factory to recreate the same addresses 505 makeAccounts := func(num int) map[common.Hash][]byte { 506 accounts := make(map[common.Hash][]byte) 507 for i := 0; i < num; i++ { 508 h := common.Hash{} 509 binary.BigEndian.PutUint64(h[:], uint64(i+1)) 510 accounts[h] = randomAccount() 511 } 512 return accounts 513 } 514 // Build up a large stack of snapshots 515 base := &diskLayer{ 516 diskdb: rawdb.NewMemoryDatabase(), 517 root: common.HexToHash("0x01"), 518 cache: fastcache.New(1024 * 500), 519 } 520 snaps := &Tree{ 521 layers: map[common.Hash]snapshot{ 522 base.root: base, 523 }, 524 } 525 for i := 1; i < 128; i++ { 526 snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil) 527 } 528 // Iterate the entire stack and ensure everything is hit only once 529 head := snaps.Snapshot(common.HexToHash("0x80")) 530 verifyIterator(t, 200, head.(snapshot).AccountIterator(common.Hash{}), verifyNothing) 531 verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) 532 533 it, _ := snaps.AccountIterator(common.HexToHash("0x80"), common.Hash{}) 534 verifyIterator(t, 200, it, verifyAccount) 535 it.Release() 536 537 // Test after persist some bottom-most layers into the disk, 538 // the functionalities still work. 539 limit := aggregatorMemoryLimit 540 defer func() { 541 aggregatorMemoryLimit = limit 542 }() 543 aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk 544 snaps.Cap(common.HexToHash("0x80"), 2) 545 546 verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount) 547 548 it, _ = snaps.AccountIterator(common.HexToHash("0x80"), common.Hash{}) 549 verifyIterator(t, 200, it, verifyAccount) 550 it.Release() 551 } 552 553 // TestAccountIteratorFlattening tests what happens when we 554 // - have a live iterator on child C (parent C1 -> C2 .. CN) 555 // - flattens C2 all the way into CN 556 // - continues iterating 557 func TestAccountIteratorFlattening(t *testing.T) { 558 // Create an empty base layer and a snapshot tree out of it 559 base := &diskLayer{ 560 diskdb: rawdb.NewMemoryDatabase(), 561 root: common.HexToHash("0x01"), 562 cache: fastcache.New(1024 * 500), 563 } 564 snaps := &Tree{ 565 layers: map[common.Hash]snapshot{ 566 base.root: base, 567 }, 568 } 569 // Create a stack of diffs on top 570 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, 571 randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil) 572 573 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, 574 randomAccountSet("0xbb", "0xdd", "0xf0"), nil) 575 576 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, 577 randomAccountSet("0xcc", "0xf0", "0xff"), nil) 578 579 // Create an iterator and flatten the data from underneath it 580 it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{}) 581 defer it.Release() 582 583 if err := snaps.Cap(common.HexToHash("0x04"), 1); err != nil { 584 t.Fatalf("failed to flatten snapshot stack: %v", err) 585 } 586 //verifyIterator(t, 7, it) 587 } 588 589 func TestAccountIteratorSeek(t *testing.T) { 590 // Create a snapshot stack with some initial data 591 base := &diskLayer{ 592 diskdb: rawdb.NewMemoryDatabase(), 593 root: common.HexToHash("0x01"), 594 cache: fastcache.New(1024 * 500), 595 } 596 snaps := &Tree{ 597 layers: map[common.Hash]snapshot{ 598 base.root: base, 599 }, 600 } 601 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, 602 randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil) 603 604 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, 605 randomAccountSet("0xbb", "0xdd", "0xf0"), nil) 606 607 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, 608 randomAccountSet("0xcc", "0xf0", "0xff"), nil) 609 610 // Account set is now 611 // 02: aa, ee, f0, ff 612 // 03: aa, bb, dd, ee, f0 (, f0), ff 613 // 04: aa, bb, cc, dd, ee, f0 (, f0), ff (, ff) 614 // Construct various iterators and ensure their traversal is correct 615 it, _ := snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xdd")) 616 defer it.Release() 617 verifyIterator(t, 3, it, verifyAccount) // expected: ee, f0, ff 618 619 it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xaa")) 620 defer it.Release() 621 verifyIterator(t, 4, it, verifyAccount) // expected: aa, ee, f0, ff 622 623 it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff")) 624 defer it.Release() 625 verifyIterator(t, 1, it, verifyAccount) // expected: ff 626 627 it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff1")) 628 defer it.Release() 629 verifyIterator(t, 0, it, verifyAccount) // expected: nothing 630 631 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xbb")) 632 defer it.Release() 633 verifyIterator(t, 6, it, verifyAccount) // expected: bb, cc, dd, ee, f0, ff 634 635 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xef")) 636 defer it.Release() 637 verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff 638 639 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xf0")) 640 defer it.Release() 641 verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff 642 643 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff")) 644 defer it.Release() 645 verifyIterator(t, 1, it, verifyAccount) // expected: ff 646 647 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff1")) 648 defer it.Release() 649 verifyIterator(t, 0, it, verifyAccount) // expected: nothing 650 } 651 652 func TestStorageIteratorSeek(t *testing.T) { 653 // Create a snapshot stack with some initial data 654 base := &diskLayer{ 655 diskdb: rawdb.NewMemoryDatabase(), 656 root: common.HexToHash("0x01"), 657 cache: fastcache.New(1024 * 500), 658 } 659 snaps := &Tree{ 660 layers: map[common.Hash]snapshot{ 661 base.root: base, 662 }, 663 } 664 // Stack three diff layers on top with various overlaps 665 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, 666 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil)) 667 668 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, 669 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil)) 670 671 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, 672 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil)) 673 674 // Account set is now 675 // 02: 01, 03, 05 676 // 03: 01, 02, 03, 05 (, 05), 06 677 // 04: 01(, 01), 02, 03, 05(, 05, 05), 06, 08 678 // Construct various iterators and ensure their traversal is correct 679 it, _ := snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x01")) 680 defer it.Release() 681 verifyIterator(t, 3, it, verifyStorage) // expected: 01, 03, 05 682 683 it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x02")) 684 defer it.Release() 685 verifyIterator(t, 2, it, verifyStorage) // expected: 03, 05 686 687 it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x5")) 688 defer it.Release() 689 verifyIterator(t, 1, it, verifyStorage) // expected: 05 690 691 it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x6")) 692 defer it.Release() 693 verifyIterator(t, 0, it, verifyStorage) // expected: nothing 694 695 it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x01")) 696 defer it.Release() 697 verifyIterator(t, 6, it, verifyStorage) // expected: 01, 02, 03, 05, 06, 08 698 699 it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x05")) 700 defer it.Release() 701 verifyIterator(t, 3, it, verifyStorage) // expected: 05, 06, 08 702 703 it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x08")) 704 defer it.Release() 705 verifyIterator(t, 1, it, verifyStorage) // expected: 08 706 707 it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x09")) 708 defer it.Release() 709 verifyIterator(t, 0, it, verifyStorage) // expected: nothing 710 } 711 712 // TestAccountIteratorDeletions tests that the iterator behaves correct when there are 713 // deleted accounts (where the Account() value is nil). The iterator 714 // should not output any accounts or nil-values for those cases. 715 func TestAccountIteratorDeletions(t *testing.T) { 716 // Create an empty base layer and a snapshot tree out of it 717 base := &diskLayer{ 718 diskdb: rawdb.NewMemoryDatabase(), 719 root: common.HexToHash("0x01"), 720 cache: fastcache.New(1024 * 500), 721 } 722 snaps := &Tree{ 723 layers: map[common.Hash]snapshot{ 724 base.root: base, 725 }, 726 } 727 // Stack three diff layers on top with various overlaps 728 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), 729 nil, randomAccountSet("0x11", "0x22", "0x33"), nil) 730 731 deleted := common.HexToHash("0x22") 732 destructed := map[common.Hash]struct{}{ 733 deleted: {}, 734 } 735 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), 736 destructed, randomAccountSet("0x11", "0x33"), nil) 737 738 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), 739 nil, randomAccountSet("0x33", "0x44", "0x55"), nil) 740 741 // The output should be 11,33,44,55 742 it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{}) 743 // Do a quick check 744 verifyIterator(t, 4, it, verifyAccount) 745 it.Release() 746 747 // And a more detailed verification that we indeed do not see '0x22' 748 it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{}) 749 defer it.Release() 750 for it.Next() { 751 hash := it.Hash() 752 if it.Account() == nil { 753 t.Errorf("iterator returned nil-value for hash %x", hash) 754 } 755 if hash == deleted { 756 t.Errorf("expected deleted elem %x to not be returned by iterator", deleted) 757 } 758 } 759 } 760 761 func TestStorageIteratorDeletions(t *testing.T) { 762 // Create an empty base layer and a snapshot tree out of it 763 base := &diskLayer{ 764 diskdb: rawdb.NewMemoryDatabase(), 765 root: common.HexToHash("0x01"), 766 cache: fastcache.New(1024 * 500), 767 } 768 snaps := &Tree{ 769 layers: map[common.Hash]snapshot{ 770 base.root: base, 771 }, 772 } 773 // Stack three diff layers on top with various overlaps 774 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, 775 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil)) 776 777 snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, 778 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}})) 779 780 // The output should be 02,04,05,06 781 it, _ := snaps.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{}) 782 verifyIterator(t, 4, it, verifyStorage) 783 it.Release() 784 785 // The output should be 04,05,06 786 it, _ = snaps.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.HexToHash("0x03")) 787 verifyIterator(t, 3, it, verifyStorage) 788 it.Release() 789 790 // Destruct the whole storage 791 destructed := map[common.Hash]struct{}{ 792 common.HexToHash("0xaa"): {}, 793 } 794 snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), destructed, nil, nil) 795 796 it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{}) 797 verifyIterator(t, 0, it, verifyStorage) 798 it.Release() 799 800 // Re-insert the slots of the same account 801 snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), nil, 802 randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil)) 803 804 // The output should be 07,08,09 805 it, _ = snaps.StorageIterator(common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{}) 806 verifyIterator(t, 3, it, verifyStorage) 807 it.Release() 808 809 // Destruct the whole storage but re-create the account in the same layer 810 snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), destructed, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, nil)) 811 it, _ = snaps.StorageIterator(common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{}) 812 verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12 813 it.Release() 814 815 verifyIterator(t, 2, snaps.Snapshot(common.HexToHash("0x06")).(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) 816 } 817 818 // BenchmarkAccountIteratorTraversal is a bit a bit notorious -- all layers contain the 819 // exact same 200 accounts. That means that we need to process 2000 items, but 820 // only spit out 200 values eventually. 821 // 822 // The value-fetching benchmark is easy on the binary iterator, since it never has to reach 823 // down at any depth for retrieving the values -- all are on the topmost layer 824 // 825 // BenchmarkAccountIteratorTraversal/binary_iterator_keys-6 2239 483674 ns/op 826 // BenchmarkAccountIteratorTraversal/binary_iterator_values-6 2403 501810 ns/op 827 // BenchmarkAccountIteratorTraversal/fast_iterator_keys-6 1923 677966 ns/op 828 // BenchmarkAccountIteratorTraversal/fast_iterator_values-6 1741 649967 ns/op 829 func BenchmarkAccountIteratorTraversal(b *testing.B) { 830 // Create a custom account factory to recreate the same addresses 831 makeAccounts := func(num int) map[common.Hash][]byte { 832 accounts := make(map[common.Hash][]byte) 833 for i := 0; i < num; i++ { 834 h := common.Hash{} 835 binary.BigEndian.PutUint64(h[:], uint64(i+1)) 836 accounts[h] = randomAccount() 837 } 838 return accounts 839 } 840 // Build up a large stack of snapshots 841 base := &diskLayer{ 842 diskdb: rawdb.NewMemoryDatabase(), 843 root: common.HexToHash("0x01"), 844 cache: fastcache.New(1024 * 500), 845 } 846 snaps := &Tree{ 847 layers: map[common.Hash]snapshot{ 848 base.root: base, 849 }, 850 } 851 for i := 1; i <= 100; i++ { 852 snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil) 853 } 854 // We call this once before the benchmark, so the creation of 855 // sorted accountlists are not included in the results. 856 head := snaps.Snapshot(common.HexToHash("0x65")) 857 head.(*diffLayer).newBinaryAccountIterator() 858 859 b.Run("binary iterator keys", func(b *testing.B) { 860 for i := 0; i < b.N; i++ { 861 got := 0 862 it := head.(*diffLayer).newBinaryAccountIterator() 863 for it.Next() { 864 got++ 865 } 866 if exp := 200; got != exp { 867 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 868 } 869 } 870 }) 871 b.Run("binary iterator values", func(b *testing.B) { 872 for i := 0; i < b.N; i++ { 873 got := 0 874 it := head.(*diffLayer).newBinaryAccountIterator() 875 for it.Next() { 876 got++ 877 head.(*diffLayer).accountRLP(it.Hash(), 0) 878 } 879 if exp := 200; got != exp { 880 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 881 } 882 } 883 }) 884 b.Run("fast iterator keys", func(b *testing.B) { 885 for i := 0; i < b.N; i++ { 886 it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) 887 defer it.Release() 888 889 got := 0 890 for it.Next() { 891 got++ 892 } 893 if exp := 200; got != exp { 894 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 895 } 896 } 897 }) 898 b.Run("fast iterator values", func(b *testing.B) { 899 for i := 0; i < b.N; i++ { 900 it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) 901 defer it.Release() 902 903 got := 0 904 for it.Next() { 905 got++ 906 it.Account() 907 } 908 if exp := 200; got != exp { 909 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 910 } 911 } 912 }) 913 } 914 915 // BenchmarkAccountIteratorLargeBaselayer is a pretty realistic benchmark, where 916 // the baselayer is a lot larger than the upper layer. 917 // 918 // This is heavy on the binary iterator, which in most cases will have to 919 // call recursively 100 times for the majority of the values 920 // 921 // BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(keys)-6 514 1971999 ns/op 922 // BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(values)-6 61 18997492 ns/op 923 // BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(keys)-6 10000 114385 ns/op 924 // BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(values)-6 4047 296823 ns/op 925 func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { 926 // Create a custom account factory to recreate the same addresses 927 makeAccounts := func(num int) map[common.Hash][]byte { 928 accounts := make(map[common.Hash][]byte) 929 for i := 0; i < num; i++ { 930 h := common.Hash{} 931 binary.BigEndian.PutUint64(h[:], uint64(i+1)) 932 accounts[h] = randomAccount() 933 } 934 return accounts 935 } 936 // Build up a large stack of snapshots 937 base := &diskLayer{ 938 diskdb: rawdb.NewMemoryDatabase(), 939 root: common.HexToHash("0x01"), 940 cache: fastcache.New(1024 * 500), 941 } 942 snaps := &Tree{ 943 layers: map[common.Hash]snapshot{ 944 base.root: base, 945 }, 946 } 947 snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, makeAccounts(2000), nil) 948 for i := 2; i <= 100; i++ { 949 snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(20), nil) 950 } 951 // We call this once before the benchmark, so the creation of 952 // sorted accountlists are not included in the results. 953 head := snaps.Snapshot(common.HexToHash("0x65")) 954 head.(*diffLayer).newBinaryAccountIterator() 955 956 b.Run("binary iterator (keys)", func(b *testing.B) { 957 for i := 0; i < b.N; i++ { 958 got := 0 959 it := head.(*diffLayer).newBinaryAccountIterator() 960 for it.Next() { 961 got++ 962 } 963 if exp := 2000; got != exp { 964 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 965 } 966 } 967 }) 968 b.Run("binary iterator (values)", func(b *testing.B) { 969 for i := 0; i < b.N; i++ { 970 got := 0 971 it := head.(*diffLayer).newBinaryAccountIterator() 972 for it.Next() { 973 got++ 974 v := it.Hash() 975 head.(*diffLayer).accountRLP(v, 0) 976 } 977 if exp := 2000; got != exp { 978 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 979 } 980 } 981 }) 982 b.Run("fast iterator (keys)", func(b *testing.B) { 983 for i := 0; i < b.N; i++ { 984 it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) 985 defer it.Release() 986 987 got := 0 988 for it.Next() { 989 got++ 990 } 991 if exp := 2000; got != exp { 992 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 993 } 994 } 995 }) 996 b.Run("fast iterator (values)", func(b *testing.B) { 997 for i := 0; i < b.N; i++ { 998 it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) 999 defer it.Release() 1000 1001 got := 0 1002 for it.Next() { 1003 it.Account() 1004 got++ 1005 } 1006 if exp := 2000; got != exp { 1007 b.Errorf("iterator len wrong, expected %d, got %d", exp, got) 1008 } 1009 } 1010 }) 1011 } 1012 1013 /* 1014 func BenchmarkBinaryAccountIteration(b *testing.B) { 1015 benchmarkAccountIteration(b, func(snap snapshot) AccountIterator { 1016 return snap.(*diffLayer).newBinaryAccountIterator() 1017 }) 1018 } 1019 1020 func BenchmarkFastAccountIteration(b *testing.B) { 1021 benchmarkAccountIteration(b, newFastAccountIterator) 1022 } 1023 1024 func benchmarkAccountIteration(b *testing.B, iterator func(snap snapshot) AccountIterator) { 1025 // Create a diff stack and randomize the accounts across them 1026 layers := make([]map[common.Hash][]byte, 128) 1027 for i := 0; i < len(layers); i++ { 1028 layers[i] = make(map[common.Hash][]byte) 1029 } 1030 for i := 0; i < b.N; i++ { 1031 depth := rand.Intn(len(layers)) 1032 layers[depth][randomHash()] = randomAccount() 1033 } 1034 stack := snapshot(emptyLayer()) 1035 for _, layer := range layers { 1036 stack = stack.Update(common.Hash{}, layer, nil, nil) 1037 } 1038 // Reset the timers and report all the stats 1039 it := iterator(stack) 1040 1041 b.ResetTimer() 1042 b.ReportAllocs() 1043 1044 for it.Next() { 1045 } 1046 } 1047 */