trie_prefetcher_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright 2021 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 state
  17. import (
  18. "math/big"
  19. "testing"
  20. "time"
  21. "github.com/ethereum/go-ethereum/common"
  22. "github.com/ethereum/go-ethereum/core/rawdb"
  23. )
  24. func filledStateDB() *StateDB {
  25. state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
  26. // Create an account and check if the retrieved balance is correct
  27. addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
  28. skey := common.HexToHash("aaa")
  29. sval := common.HexToHash("bbb")
  30. state.SetBalance(addr, big.NewInt(42)) // Change the account trie
  31. state.SetCode(addr, []byte("hello")) // Change an external metadata
  32. state.SetState(addr, skey, sval) // Change the storage trie
  33. for i := 0; i < 100; i++ {
  34. sk := common.BigToHash(big.NewInt(int64(i)))
  35. state.SetState(addr, sk, sk) // Change the storage trie
  36. }
  37. return state
  38. }
  39. func TestCopyAndClose(t *testing.T) {
  40. db := filledStateDB()
  41. prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
  42. skey := common.HexToHash("aaa")
  43. prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  44. prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  45. time.Sleep(1 * time.Second)
  46. a := prefetcher.trie(common.Hash{}, db.originalRoot)
  47. prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  48. b := prefetcher.trie(common.Hash{}, db.originalRoot)
  49. cpy := prefetcher.copy()
  50. cpy.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  51. cpy.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  52. c := cpy.trie(common.Hash{}, db.originalRoot)
  53. prefetcher.close()
  54. cpy2 := cpy.copy()
  55. cpy2.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  56. d := cpy2.trie(common.Hash{}, db.originalRoot)
  57. cpy.close()
  58. cpy2.close()
  59. if a.Hash() != b.Hash() || a.Hash() != c.Hash() || a.Hash() != d.Hash() {
  60. t.Fatalf("Invalid trie, hashes should be equal: %v %v %v %v", a.Hash(), b.Hash(), c.Hash(), d.Hash())
  61. }
  62. }
  63. func TestUseAfterClose(t *testing.T) {
  64. db := filledStateDB()
  65. prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
  66. skey := common.HexToHash("aaa")
  67. prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  68. a := prefetcher.trie(common.Hash{}, db.originalRoot)
  69. prefetcher.close()
  70. b := prefetcher.trie(common.Hash{}, db.originalRoot)
  71. if a == nil {
  72. t.Fatal("Prefetching before close should not return nil")
  73. }
  74. if b != nil {
  75. t.Fatal("Trie after close should return nil")
  76. }
  77. }
  78. func TestCopyClose(t *testing.T) {
  79. db := filledStateDB()
  80. prefetcher := newTriePrefetcher(db.db, db.originalRoot, "")
  81. skey := common.HexToHash("aaa")
  82. prefetcher.prefetch(common.Hash{}, db.originalRoot, [][]byte{skey.Bytes()})
  83. cpy := prefetcher.copy()
  84. a := prefetcher.trie(common.Hash{}, db.originalRoot)
  85. b := cpy.trie(common.Hash{}, db.originalRoot)
  86. prefetcher.close()
  87. c := prefetcher.trie(common.Hash{}, db.originalRoot)
  88. d := cpy.trie(common.Hash{}, db.originalRoot)
  89. if a == nil {
  90. t.Fatal("Prefetching before close should not return nil")
  91. }
  92. if b == nil {
  93. t.Fatal("Copy trie should return nil")
  94. }
  95. if c != nil {
  96. t.Fatal("Trie after close should return nil")
  97. }
  98. if d == nil {
  99. t.Fatal("Copy trie should not return nil")
  100. }
  101. }