difflayer_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  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. package snapshot
  17. import (
  18. "bytes"
  19. "encoding/binary"
  20. "math/big"
  21. "math/rand"
  22. "testing"
  23. "github.com/VictoriaMetrics/fastcache"
  24. "github.com/ethereum/go-ethereum/common"
  25. "github.com/ethereum/go-ethereum/crypto"
  26. "github.com/ethereum/go-ethereum/ethdb/memorydb"
  27. "github.com/ethereum/go-ethereum/rlp"
  28. )
  29. func randomAccount() []byte {
  30. root := randomHash()
  31. a := Account{
  32. Balance: big.NewInt(rand.Int63()),
  33. Nonce: rand.Uint64(),
  34. Root: root[:],
  35. CodeHash: emptyCode[:],
  36. }
  37. data, _ := rlp.EncodeToBytes(a)
  38. return data
  39. }
  40. // TestMergeBasics tests some simple merges
  41. func TestMergeBasics(t *testing.T) {
  42. var (
  43. accounts = make(map[common.Hash][]byte)
  44. storage = make(map[common.Hash]map[common.Hash][]byte)
  45. )
  46. // Fill up a parent
  47. for i := 0; i < 100; i++ {
  48. h := randomHash()
  49. data := randomAccount()
  50. accounts[h] = data
  51. if rand.Intn(20) < 10 {
  52. accStorage := make(map[common.Hash][]byte)
  53. value := make([]byte, 32)
  54. rand.Read(value)
  55. accStorage[randomHash()] = value
  56. storage[h] = accStorage
  57. }
  58. }
  59. // Add some (identical) layers on top
  60. parent := newDiffLayer(emptyLayer(), common.Hash{}, accounts, storage)
  61. child := newDiffLayer(parent, common.Hash{}, accounts, storage)
  62. child = newDiffLayer(child, common.Hash{}, accounts, storage)
  63. child = newDiffLayer(child, common.Hash{}, accounts, storage)
  64. child = newDiffLayer(child, common.Hash{}, accounts, storage)
  65. // And flatten
  66. merged := (child.flatten()).(*diffLayer)
  67. { // Check account lists
  68. // Should be zero/nil first
  69. if got, exp := len(merged.accountList), 0; got != exp {
  70. t.Errorf("accountList wrong, got %v exp %v", got, exp)
  71. }
  72. // Then set when we call AccountList
  73. if got, exp := len(merged.AccountList()), len(accounts); got != exp {
  74. t.Errorf("AccountList() wrong, got %v exp %v", got, exp)
  75. }
  76. if got, exp := len(merged.accountList), len(accounts); got != exp {
  77. t.Errorf("accountList [2] wrong, got %v exp %v", got, exp)
  78. }
  79. }
  80. { // Check storage lists
  81. i := 0
  82. for aHash, sMap := range storage {
  83. if got, exp := len(merged.storageList), i; got != exp {
  84. t.Errorf("[1] storageList wrong, got %v exp %v", got, exp)
  85. }
  86. if got, exp := len(merged.StorageList(aHash)), len(sMap); got != exp {
  87. t.Errorf("[2] StorageList() wrong, got %v exp %v", got, exp)
  88. }
  89. if got, exp := len(merged.storageList[aHash]), len(sMap); got != exp {
  90. t.Errorf("storageList wrong, got %v exp %v", got, exp)
  91. }
  92. i++
  93. }
  94. }
  95. }
  96. // TestMergeDelete tests some deletion
  97. func TestMergeDelete(t *testing.T) {
  98. var (
  99. storage = make(map[common.Hash]map[common.Hash][]byte)
  100. )
  101. // Fill up a parent
  102. h1 := common.HexToHash("0x01")
  103. h2 := common.HexToHash("0x02")
  104. flip := func() map[common.Hash][]byte {
  105. accs := make(map[common.Hash][]byte)
  106. accs[h1] = randomAccount()
  107. accs[h2] = nil
  108. return accs
  109. }
  110. flop := func() map[common.Hash][]byte {
  111. accs := make(map[common.Hash][]byte)
  112. accs[h1] = nil
  113. accs[h2] = randomAccount()
  114. return accs
  115. }
  116. // Add some flip-flopping layers on top
  117. parent := newDiffLayer(emptyLayer(), common.Hash{}, flip(), storage)
  118. child := parent.Update(common.Hash{}, flop(), storage)
  119. child = child.Update(common.Hash{}, flip(), storage)
  120. child = child.Update(common.Hash{}, flop(), storage)
  121. child = child.Update(common.Hash{}, flip(), storage)
  122. child = child.Update(common.Hash{}, flop(), storage)
  123. child = child.Update(common.Hash{}, flip(), storage)
  124. if data, _ := child.Account(h1); data == nil {
  125. t.Errorf("last diff layer: expected %x to be non-nil", h1)
  126. }
  127. if data, _ := child.Account(h2); data != nil {
  128. t.Errorf("last diff layer: expected %x to be nil", h2)
  129. }
  130. // And flatten
  131. merged := (child.flatten()).(*diffLayer)
  132. if data, _ := merged.Account(h1); data == nil {
  133. t.Errorf("merged layer: expected %x to be non-nil", h1)
  134. }
  135. if data, _ := merged.Account(h2); data != nil {
  136. t.Errorf("merged layer: expected %x to be nil", h2)
  137. }
  138. // If we add more granular metering of memory, we can enable this again,
  139. // but it's not implemented for now
  140. //if got, exp := merged.memory, child.memory; got != exp {
  141. // t.Errorf("mem wrong, got %d, exp %d", got, exp)
  142. //}
  143. }
  144. // This tests that if we create a new account, and set a slot, and then merge
  145. // it, the lists will be correct.
  146. func TestInsertAndMerge(t *testing.T) {
  147. // Fill up a parent
  148. var (
  149. acc = common.HexToHash("0x01")
  150. slot = common.HexToHash("0x02")
  151. parent *diffLayer
  152. child *diffLayer
  153. )
  154. {
  155. var accounts = make(map[common.Hash][]byte)
  156. var storage = make(map[common.Hash]map[common.Hash][]byte)
  157. parent = newDiffLayer(emptyLayer(), common.Hash{}, accounts, storage)
  158. }
  159. {
  160. var accounts = make(map[common.Hash][]byte)
  161. var storage = make(map[common.Hash]map[common.Hash][]byte)
  162. accounts[acc] = randomAccount()
  163. accstorage := make(map[common.Hash][]byte)
  164. storage[acc] = accstorage
  165. storage[acc][slot] = []byte{0x01}
  166. child = newDiffLayer(parent, common.Hash{}, accounts, storage)
  167. }
  168. // And flatten
  169. merged := (child.flatten()).(*diffLayer)
  170. { // Check that slot value is present
  171. got, _ := merged.Storage(acc, slot)
  172. if exp := []byte{0x01}; bytes.Compare(got, exp) != 0 {
  173. t.Errorf("merged slot value wrong, got %x, exp %x", got, exp)
  174. }
  175. }
  176. }
  177. func emptyLayer() *diskLayer {
  178. return &diskLayer{
  179. diskdb: memorydb.New(),
  180. cache: fastcache.New(500 * 1024),
  181. }
  182. }
  183. // BenchmarkSearch checks how long it takes to find a non-existing key
  184. // BenchmarkSearch-6 200000 10481 ns/op (1K per layer)
  185. // BenchmarkSearch-6 200000 10760 ns/op (10K per layer)
  186. // BenchmarkSearch-6 100000 17866 ns/op
  187. //
  188. // BenchmarkSearch-6 500000 3723 ns/op (10k per layer, only top-level RLock()
  189. func BenchmarkSearch(b *testing.B) {
  190. // First, we set up 128 diff layers, with 1K items each
  191. fill := func(parent snapshot) *diffLayer {
  192. accounts := make(map[common.Hash][]byte)
  193. storage := make(map[common.Hash]map[common.Hash][]byte)
  194. for i := 0; i < 10000; i++ {
  195. accounts[randomHash()] = randomAccount()
  196. }
  197. return newDiffLayer(parent, common.Hash{}, accounts, storage)
  198. }
  199. var layer snapshot
  200. layer = emptyLayer()
  201. for i := 0; i < 128; i++ {
  202. layer = fill(layer)
  203. }
  204. key := crypto.Keccak256Hash([]byte{0x13, 0x38})
  205. b.ResetTimer()
  206. for i := 0; i < b.N; i++ {
  207. layer.AccountRLP(key)
  208. }
  209. }
  210. // BenchmarkSearchSlot checks how long it takes to find a non-existing key
  211. // - Number of layers: 128
  212. // - Each layers contains the account, with a couple of storage slots
  213. // BenchmarkSearchSlot-6 100000 14554 ns/op
  214. // BenchmarkSearchSlot-6 100000 22254 ns/op (when checking parent root using mutex)
  215. // BenchmarkSearchSlot-6 100000 14551 ns/op (when checking parent number using atomic)
  216. // With bloom filter:
  217. // BenchmarkSearchSlot-6 3467835 351 ns/op
  218. func BenchmarkSearchSlot(b *testing.B) {
  219. // First, we set up 128 diff layers, with 1K items each
  220. accountKey := crypto.Keccak256Hash([]byte{0x13, 0x37})
  221. storageKey := crypto.Keccak256Hash([]byte{0x13, 0x37})
  222. accountRLP := randomAccount()
  223. fill := func(parent snapshot) *diffLayer {
  224. accounts := make(map[common.Hash][]byte)
  225. accounts[accountKey] = accountRLP
  226. storage := make(map[common.Hash]map[common.Hash][]byte)
  227. accStorage := make(map[common.Hash][]byte)
  228. for i := 0; i < 5; i++ {
  229. value := make([]byte, 32)
  230. rand.Read(value)
  231. accStorage[randomHash()] = value
  232. storage[accountKey] = accStorage
  233. }
  234. return newDiffLayer(parent, common.Hash{}, accounts, storage)
  235. }
  236. var layer snapshot
  237. layer = emptyLayer()
  238. for i := 0; i < 128; i++ {
  239. layer = fill(layer)
  240. }
  241. b.ResetTimer()
  242. for i := 0; i < b.N; i++ {
  243. layer.Storage(accountKey, storageKey)
  244. }
  245. }
  246. // With accountList and sorting
  247. //BenchmarkFlatten-6 50 29890856 ns/op
  248. //
  249. // Without sorting and tracking accountlist
  250. // BenchmarkFlatten-6 300 5511511 ns/op
  251. func BenchmarkFlatten(b *testing.B) {
  252. fill := func(parent snapshot) *diffLayer {
  253. accounts := make(map[common.Hash][]byte)
  254. storage := make(map[common.Hash]map[common.Hash][]byte)
  255. for i := 0; i < 100; i++ {
  256. accountKey := randomHash()
  257. accounts[accountKey] = randomAccount()
  258. accStorage := make(map[common.Hash][]byte)
  259. for i := 0; i < 20; i++ {
  260. value := make([]byte, 32)
  261. rand.Read(value)
  262. accStorage[randomHash()] = value
  263. }
  264. storage[accountKey] = accStorage
  265. }
  266. return newDiffLayer(parent, common.Hash{}, accounts, storage)
  267. }
  268. b.ResetTimer()
  269. for i := 0; i < b.N; i++ {
  270. b.StopTimer()
  271. var layer snapshot
  272. layer = emptyLayer()
  273. for i := 1; i < 128; i++ {
  274. layer = fill(layer)
  275. }
  276. b.StartTimer()
  277. for i := 1; i < 128; i++ {
  278. dl, ok := layer.(*diffLayer)
  279. if !ok {
  280. break
  281. }
  282. layer = dl.flatten()
  283. }
  284. b.StopTimer()
  285. }
  286. }
  287. // This test writes ~324M of diff layers to disk, spread over
  288. // - 128 individual layers,
  289. // - each with 200 accounts
  290. // - containing 200 slots
  291. //
  292. // BenchmarkJournal-6 1 1471373923 ns/ops
  293. // BenchmarkJournal-6 1 1208083335 ns/op // bufio writer
  294. func BenchmarkJournal(b *testing.B) {
  295. fill := func(parent snapshot) *diffLayer {
  296. accounts := make(map[common.Hash][]byte)
  297. storage := make(map[common.Hash]map[common.Hash][]byte)
  298. for i := 0; i < 200; i++ {
  299. accountKey := randomHash()
  300. accounts[accountKey] = randomAccount()
  301. accStorage := make(map[common.Hash][]byte)
  302. for i := 0; i < 200; i++ {
  303. value := make([]byte, 32)
  304. rand.Read(value)
  305. accStorage[randomHash()] = value
  306. }
  307. storage[accountKey] = accStorage
  308. }
  309. return newDiffLayer(parent, common.Hash{}, accounts, storage)
  310. }
  311. layer := snapshot(new(diskLayer))
  312. for i := 1; i < 128; i++ {
  313. layer = fill(layer)
  314. }
  315. b.ResetTimer()
  316. for i := 0; i < b.N; i++ {
  317. layer.Journal(new(bytes.Buffer))
  318. }
  319. }
  320. // TestIteratorBasics tests some simple single-layer iteration
  321. func TestIteratorBasics(t *testing.T) {
  322. var (
  323. accounts = make(map[common.Hash][]byte)
  324. storage = make(map[common.Hash]map[common.Hash][]byte)
  325. )
  326. // Fill up a parent
  327. for i := 0; i < 100; i++ {
  328. h := randomHash()
  329. data := randomAccount()
  330. accounts[h] = data
  331. if rand.Intn(20) < 10 {
  332. accStorage := make(map[common.Hash][]byte)
  333. value := make([]byte, 32)
  334. rand.Read(value)
  335. accStorage[randomHash()] = value
  336. storage[h] = accStorage
  337. }
  338. }
  339. // Add some (identical) layers on top
  340. parent := newDiffLayer(emptyLayer{}, common.Hash{}, accounts, storage)
  341. it := parent.newIterator()
  342. verifyIterator(t, 100, it)
  343. }
  344. type testIterator struct {
  345. values []byte
  346. }
  347. func newTestIterator(values ...byte) *testIterator {
  348. return &testIterator{values}
  349. }
  350. func (ti *testIterator) Next() bool {
  351. ti.values = ti.values[1:]
  352. if len(ti.values) == 0 {
  353. return false
  354. }
  355. return true
  356. }
  357. func (ti *testIterator) Key() common.Hash {
  358. return common.BytesToHash([]byte{ti.values[0]})
  359. }
  360. func (ti *testIterator) Seek(common.Hash) {
  361. panic("implement me")
  362. }
  363. func TestFastIteratorBasics(t *testing.T) {
  364. type testCase struct {
  365. lists [][]byte
  366. expKeys []byte
  367. }
  368. for i, tc := range []testCase{
  369. {lists: [][]byte{{0, 1, 8}, {1, 2, 8}, {2, 9}, {4},
  370. {7, 14, 15}, {9, 13, 15, 16}},
  371. expKeys: []byte{0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16}},
  372. {lists: [][]byte{{0, 8}, {1, 2, 8}, {7, 14, 15}, {8, 9},
  373. {9, 10}, {10, 13, 15, 16}},
  374. expKeys: []byte{0, 1, 2, 7, 8, 9, 10, 13, 14, 15, 16}},
  375. } {
  376. var iterators []Iterator
  377. for _, data := range tc.lists {
  378. iterators = append(iterators, newTestIterator(data...))
  379. }
  380. fi := &fastIterator{
  381. iterators: iterators,
  382. initiated: false,
  383. }
  384. count := 0
  385. for fi.Next() {
  386. if got, exp := fi.Key()[31], tc.expKeys[count]; exp != got {
  387. t.Errorf("tc %d, [%d]: got %d exp %d", i, count, got, exp)
  388. }
  389. count++
  390. }
  391. }
  392. }
  393. func verifyIterator(t *testing.T, expCount int, it Iterator) {
  394. var (
  395. i = 0
  396. last = common.Hash{}
  397. )
  398. for it.Next() {
  399. v := it.Key()
  400. if bytes.Compare(last[:], v[:]) >= 0 {
  401. t.Errorf("Wrong order:\n%x \n>=\n%x", last, v)
  402. }
  403. i++
  404. }
  405. if i != expCount {
  406. t.Errorf("iterator len wrong, expected %d, got %d", expCount, i)
  407. }
  408. }
  409. // TestIteratorTraversal tests some simple multi-layer iteration
  410. func TestIteratorTraversal(t *testing.T) {
  411. var (
  412. storage = make(map[common.Hash]map[common.Hash][]byte)
  413. )
  414. mkAccounts := func(args ...string) map[common.Hash][]byte {
  415. accounts := make(map[common.Hash][]byte)
  416. for _, h := range args {
  417. accounts[common.HexToHash(h)] = randomAccount()
  418. }
  419. return accounts
  420. }
  421. // entries in multiple layers should only become output once
  422. parent := newDiffLayer(emptyLayer{}, common.Hash{},
  423. mkAccounts("0xaa", "0xee", "0xff", "0xf0"), storage)
  424. child := parent.Update(common.Hash{},
  425. mkAccounts("0xbb", "0xdd", "0xf0"), storage)
  426. child = child.Update(common.Hash{},
  427. mkAccounts("0xcc", "0xf0", "0xff"), storage)
  428. // single layer iterator
  429. verifyIterator(t, 3, child.newIterator())
  430. // multi-layered binary iterator
  431. verifyIterator(t, 7, child.newBinaryIterator())
  432. // multi-layered fast iterator
  433. verifyIterator(t, 7, child.newFastIterator())
  434. }
  435. func TestIteratorLargeTraversal(t *testing.T) {
  436. // This testcase is a bit notorious -- all layers contain the exact
  437. // same 200 accounts.
  438. var storage = make(map[common.Hash]map[common.Hash][]byte)
  439. mkAccounts := func(num int) map[common.Hash][]byte {
  440. accounts := make(map[common.Hash][]byte)
  441. for i := 0; i < num; i++ {
  442. h := common.Hash{}
  443. binary.BigEndian.PutUint64(h[:], uint64(i+1))
  444. accounts[h] = randomAccount()
  445. }
  446. return accounts
  447. }
  448. parent := newDiffLayer(emptyLayer{}, common.Hash{},
  449. mkAccounts(200), storage)
  450. child := parent.Update(common.Hash{},
  451. mkAccounts(200), storage)
  452. for i := 2; i < 100; i++ {
  453. child = child.Update(common.Hash{},
  454. mkAccounts(200), storage)
  455. }
  456. // single layer iterator
  457. verifyIterator(t, 200, child.newIterator())
  458. // multi-layered binary iterator
  459. verifyIterator(t, 200, child.newBinaryIterator())
  460. // multi-layered fast iterator
  461. verifyIterator(t, 200, child.newFastIterator())
  462. }
  463. // BenchmarkIteratorTraversal is a bit a bit notorious -- all layers contain the exact
  464. // same 200 accounts. That means that we need to process 2000 items, but only
  465. // spit out 200 values eventually.
  466. //
  467. //BenchmarkIteratorTraversal/binary_iterator-6 2008 573290 ns/op 9520 B/op 199 allocs/op
  468. //BenchmarkIteratorTraversal/fast_iterator-6 1946 575596 ns/op 20146 B/op 134 allocs/op
  469. func BenchmarkIteratorTraversal(b *testing.B) {
  470. var storage = make(map[common.Hash]map[common.Hash][]byte)
  471. mkAccounts := func(num int) map[common.Hash][]byte {
  472. accounts := make(map[common.Hash][]byte)
  473. for i := 0; i < num; i++ {
  474. h := common.Hash{}
  475. binary.BigEndian.PutUint64(h[:], uint64(i+1))
  476. accounts[h] = randomAccount()
  477. }
  478. return accounts
  479. }
  480. parent := newDiffLayer(emptyLayer{}, common.Hash{},
  481. mkAccounts(200), storage)
  482. child := parent.Update(common.Hash{},
  483. mkAccounts(200), storage)
  484. for i := 2; i < 100; i++ {
  485. child = child.Update(common.Hash{},
  486. mkAccounts(200), storage)
  487. }
  488. // We call this once before the benchmark, so the creation of
  489. // sorted accountlists are not included in the results.
  490. child.newBinaryIterator()
  491. b.Run("binary iterator", func(b *testing.B) {
  492. for i := 0; i < b.N; i++ {
  493. got := 0
  494. it := child.newBinaryIterator()
  495. for it.Next() {
  496. got++
  497. }
  498. if exp := 200; got != exp {
  499. b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  500. }
  501. }
  502. })
  503. b.Run("fast iterator", func(b *testing.B) {
  504. for i := 0; i < b.N; i++ {
  505. got := 0
  506. it := child.newFastIterator()
  507. for it.Next() {
  508. got++
  509. }
  510. if exp := 200; got != exp {
  511. b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  512. }
  513. }
  514. })
  515. }
  516. // BenchmarkIteratorLargeBaselayer is a pretty realistic benchmark, where
  517. // the baselayer is a lot larger than the upper layer.
  518. //
  519. // This is heavy on the binary iterator, which in most cases will have to
  520. // call recursively 100 times for the majority of the values
  521. //
  522. // BenchmarkIteratorLargeBaselayer/binary_iterator-6 585 2067377 ns/op 9520 B/op 199 allocs/op
  523. // BenchmarkIteratorLargeBaselayer/fast_iterator-6 13198 91043 ns/op 8601 B/op 118 allocs/op
  524. func BenchmarkIteratorLargeBaselayer(b *testing.B) {
  525. var storage = make(map[common.Hash]map[common.Hash][]byte)
  526. mkAccounts := func(num int) map[common.Hash][]byte {
  527. accounts := make(map[common.Hash][]byte)
  528. for i := 0; i < num; i++ {
  529. h := common.Hash{}
  530. binary.BigEndian.PutUint64(h[:], uint64(i+1))
  531. accounts[h] = randomAccount()
  532. }
  533. return accounts
  534. }
  535. parent := newDiffLayer(emptyLayer{}, common.Hash{},
  536. mkAccounts(2000), storage)
  537. child := parent.Update(common.Hash{},
  538. mkAccounts(20), storage)
  539. for i := 2; i < 100; i++ {
  540. child = child.Update(common.Hash{},
  541. mkAccounts(20), storage)
  542. }
  543. // We call this once before the benchmark, so the creation of
  544. // sorted accountlists are not included in the results.
  545. child.newBinaryIterator()
  546. b.Run("binary iterator", func(b *testing.B) {
  547. for i := 0; i < b.N; i++ {
  548. got := 0
  549. it := child.newBinaryIterator()
  550. for it.Next() {
  551. got++
  552. }
  553. if exp := 2000; got != exp {
  554. b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  555. }
  556. }
  557. })
  558. b.Run("fast iterator", func(b *testing.B) {
  559. for i := 0; i < b.N; i++ {
  560. got := 0
  561. it := child.newFastIterator()
  562. for it.Next() {
  563. got++
  564. }
  565. if exp := 2000; got != exp {
  566. b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  567. }
  568. }
  569. })
  570. }
  571. // TestIteratorFlatting tests what happens when we
  572. // - have a live iterator on child C (parent C1 -> C2 .. CN)
  573. // - flattens C2 all the way into CN
  574. // - continues iterating
  575. // Right now, this "works" simply because the keys do not change -- the
  576. // iterator is not aware that a layer has become stale. This naive
  577. // solution probably won't work in the long run, however
  578. func TestIteratorFlattning(t *testing.T) {
  579. var (
  580. storage = make(map[common.Hash]map[common.Hash][]byte)
  581. )
  582. mkAccounts := func(args ...string) map[common.Hash][]byte {
  583. accounts := make(map[common.Hash][]byte)
  584. for _, h := range args {
  585. accounts[common.HexToHash(h)] = randomAccount()
  586. }
  587. return accounts
  588. }
  589. // entries in multiple layers should only become output once
  590. parent := newDiffLayer(emptyLayer{}, common.Hash{},
  591. mkAccounts("0xaa", "0xee", "0xff", "0xf0"), storage)
  592. child := parent.Update(common.Hash{},
  593. mkAccounts("0xbb", "0xdd", "0xf0"), storage)
  594. child = child.Update(common.Hash{},
  595. mkAccounts("0xcc", "0xf0", "0xff"), storage)
  596. it := child.newFastIterator()
  597. child.parent.(*diffLayer).flatten()
  598. // The parent should now be stale
  599. verifyIterator(t, 7, it)
  600. }
  601. func TestIteratorSeek(t *testing.T) {
  602. storage := make(map[common.Hash]map[common.Hash][]byte)
  603. mkAccounts := func(args ...string) map[common.Hash][]byte {
  604. accounts := make(map[common.Hash][]byte)
  605. for _, h := range args {
  606. accounts[common.HexToHash(h)] = randomAccount()
  607. }
  608. return accounts
  609. }
  610. parent := newDiffLayer(emptyLayer{}, common.Hash{},
  611. mkAccounts("0xaa", "0xee", "0xff", "0xf0"), storage)
  612. it := parent.newIterator()
  613. // expected: ee, f0, ff
  614. it.Seek(common.HexToHash("0xdd"))
  615. verifyIterator(t, 3, it)
  616. it = parent.newIterator().(*dlIterator)
  617. // expected: ee, f0, ff
  618. it.Seek(common.HexToHash("0xaa"))
  619. verifyIterator(t, 3, it)
  620. it = parent.newIterator().(*dlIterator)
  621. // expected: nothing
  622. it.Seek(common.HexToHash("0xff"))
  623. verifyIterator(t, 0, it)
  624. child := parent.Update(common.Hash{},
  625. mkAccounts("0xbb", "0xdd", "0xf0"), storage)
  626. child = child.Update(common.Hash{},
  627. mkAccounts("0xcc", "0xf0", "0xff"), storage)
  628. it = child.newFastIterator()
  629. // expected: cc, dd, ee, f0, ff
  630. it.Seek(common.HexToHash("0xbb"))
  631. verifyIterator(t, 5, it)
  632. it = child.newFastIterator()
  633. it.Seek(common.HexToHash("0xef"))
  634. // exp: f0, ff
  635. verifyIterator(t, 2, it)
  636. it = child.newFastIterator()
  637. it.Seek(common.HexToHash("0xf0"))
  638. verifyIterator(t, 1, it)
  639. it.Seek(common.HexToHash("0xff"))
  640. verifyIterator(t, 0, it)
  641. }