filter_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // Copyright 2015 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 filters
  17. import (
  18. "context"
  19. "io/ioutil"
  20. "math/big"
  21. "os"
  22. "testing"
  23. "github.com/ethereum/go-ethereum/common"
  24. "github.com/ethereum/go-ethereum/consensus/ethash"
  25. "github.com/ethereum/go-ethereum/core"
  26. "github.com/ethereum/go-ethereum/core/rawdb"
  27. "github.com/ethereum/go-ethereum/core/types"
  28. "github.com/ethereum/go-ethereum/crypto"
  29. "github.com/ethereum/go-ethereum/ethdb"
  30. "github.com/ethereum/go-ethereum/event"
  31. "github.com/ethereum/go-ethereum/params"
  32. )
  33. func makeReceipt(addr common.Address) *types.Receipt {
  34. receipt := types.NewReceipt(nil, false, 0)
  35. receipt.Logs = []*types.Log{
  36. {Address: addr},
  37. }
  38. receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
  39. return receipt
  40. }
  41. func BenchmarkFilters(b *testing.B) {
  42. dir, err := ioutil.TempDir("", "filtertest")
  43. if err != nil {
  44. b.Fatal(err)
  45. }
  46. defer os.RemoveAll(dir)
  47. var (
  48. db, _ = ethdb.NewLDBDatabase(dir, 0, 0)
  49. mux = new(event.TypeMux)
  50. txFeed = new(event.Feed)
  51. rmLogsFeed = new(event.Feed)
  52. logsFeed = new(event.Feed)
  53. chainFeed = new(event.Feed)
  54. backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
  55. key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  56. addr1 = crypto.PubkeyToAddress(key1.PublicKey)
  57. addr2 = common.BytesToAddress([]byte("jeff"))
  58. addr3 = common.BytesToAddress([]byte("ethereum"))
  59. addr4 = common.BytesToAddress([]byte("random addresses please"))
  60. )
  61. defer db.Close()
  62. genesis := core.GenesisBlockForTesting(db, addr1, big.NewInt(1000000))
  63. chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 100010, func(i int, gen *core.BlockGen) {
  64. switch i {
  65. case 2403:
  66. receipt := makeReceipt(addr1)
  67. gen.AddUncheckedReceipt(receipt)
  68. case 1034:
  69. receipt := makeReceipt(addr2)
  70. gen.AddUncheckedReceipt(receipt)
  71. case 34:
  72. receipt := makeReceipt(addr3)
  73. gen.AddUncheckedReceipt(receipt)
  74. case 99999:
  75. receipt := makeReceipt(addr4)
  76. gen.AddUncheckedReceipt(receipt)
  77. }
  78. })
  79. for i, block := range chain {
  80. rawdb.WriteBlock(db, block)
  81. rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
  82. rawdb.WriteHeadBlockHash(db, block.Hash())
  83. rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i])
  84. }
  85. b.ResetTimer()
  86. filter := New(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil)
  87. for i := 0; i < b.N; i++ {
  88. logs, _ := filter.Logs(context.Background())
  89. if len(logs) != 4 {
  90. b.Fatal("expected 4 logs, got", len(logs))
  91. }
  92. }
  93. }
  94. func TestFilters(t *testing.T) {
  95. dir, err := ioutil.TempDir("", "filtertest")
  96. if err != nil {
  97. t.Fatal(err)
  98. }
  99. defer os.RemoveAll(dir)
  100. var (
  101. db, _ = ethdb.NewLDBDatabase(dir, 0, 0)
  102. mux = new(event.TypeMux)
  103. txFeed = new(event.Feed)
  104. rmLogsFeed = new(event.Feed)
  105. logsFeed = new(event.Feed)
  106. chainFeed = new(event.Feed)
  107. backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
  108. key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  109. addr = crypto.PubkeyToAddress(key1.PublicKey)
  110. hash1 = common.BytesToHash([]byte("topic1"))
  111. hash2 = common.BytesToHash([]byte("topic2"))
  112. hash3 = common.BytesToHash([]byte("topic3"))
  113. hash4 = common.BytesToHash([]byte("topic4"))
  114. )
  115. defer db.Close()
  116. genesis := core.GenesisBlockForTesting(db, addr, big.NewInt(1000000))
  117. chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {
  118. switch i {
  119. case 1:
  120. receipt := types.NewReceipt(nil, false, 0)
  121. receipt.Logs = []*types.Log{
  122. {
  123. Address: addr,
  124. Topics: []common.Hash{hash1},
  125. },
  126. }
  127. gen.AddUncheckedReceipt(receipt)
  128. case 2:
  129. receipt := types.NewReceipt(nil, false, 0)
  130. receipt.Logs = []*types.Log{
  131. {
  132. Address: addr,
  133. Topics: []common.Hash{hash2},
  134. },
  135. }
  136. gen.AddUncheckedReceipt(receipt)
  137. case 998:
  138. receipt := types.NewReceipt(nil, false, 0)
  139. receipt.Logs = []*types.Log{
  140. {
  141. Address: addr,
  142. Topics: []common.Hash{hash3},
  143. },
  144. }
  145. gen.AddUncheckedReceipt(receipt)
  146. case 999:
  147. receipt := types.NewReceipt(nil, false, 0)
  148. receipt.Logs = []*types.Log{
  149. {
  150. Address: addr,
  151. Topics: []common.Hash{hash4},
  152. },
  153. }
  154. gen.AddUncheckedReceipt(receipt)
  155. }
  156. })
  157. for i, block := range chain {
  158. rawdb.WriteBlock(db, block)
  159. rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
  160. rawdb.WriteHeadBlockHash(db, block.Hash())
  161. rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i])
  162. }
  163. filter := New(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
  164. logs, _ := filter.Logs(context.Background())
  165. if len(logs) != 4 {
  166. t.Error("expected 4 log, got", len(logs))
  167. }
  168. filter = New(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}})
  169. logs, _ = filter.Logs(context.Background())
  170. if len(logs) != 1 {
  171. t.Error("expected 1 log, got", len(logs))
  172. }
  173. if len(logs) > 0 && logs[0].Topics[0] != hash3 {
  174. t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
  175. }
  176. filter = New(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}})
  177. logs, _ = filter.Logs(context.Background())
  178. if len(logs) != 1 {
  179. t.Error("expected 1 log, got", len(logs))
  180. }
  181. if len(logs) > 0 && logs[0].Topics[0] != hash3 {
  182. t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
  183. }
  184. filter = New(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}})
  185. logs, _ = filter.Logs(context.Background())
  186. if len(logs) != 2 {
  187. t.Error("expected 2 log, got", len(logs))
  188. }
  189. failHash := common.BytesToHash([]byte("fail"))
  190. filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}})
  191. logs, _ = filter.Logs(context.Background())
  192. if len(logs) != 0 {
  193. t.Error("expected 0 log, got", len(logs))
  194. }
  195. failAddr := common.BytesToAddress([]byte("failmenow"))
  196. filter = New(backend, 0, -1, []common.Address{failAddr}, nil)
  197. logs, _ = filter.Logs(context.Background())
  198. if len(logs) != 0 {
  199. t.Error("expected 0 log, got", len(logs))
  200. }
  201. filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}})
  202. logs, _ = filter.Logs(context.Background())
  203. if len(logs) != 0 {
  204. t.Error("expected 0 log, got", len(logs))
  205. }
  206. }