github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/eth/filters/filter_test.go (about) 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 17 package filters 18 19 import ( 20 "context" 21 "encoding/json" 22 "math/big" 23 "strings" 24 "testing" 25 "time" 26 27 "github.com/ethereum/go-ethereum/accounts/abi" 28 "github.com/ethereum/go-ethereum/common" 29 "github.com/ethereum/go-ethereum/consensus/ethash" 30 "github.com/ethereum/go-ethereum/core" 31 "github.com/ethereum/go-ethereum/core/rawdb" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/core/vm" 34 "github.com/ethereum/go-ethereum/crypto" 35 "github.com/ethereum/go-ethereum/params" 36 "github.com/ethereum/go-ethereum/rpc" 37 "github.com/ethereum/go-ethereum/triedb" 38 ) 39 40 func makeReceipt(addr common.Address) *types.Receipt { 41 receipt := types.NewReceipt(nil, false, 0) 42 receipt.Logs = []*types.Log{ 43 {Address: addr}, 44 } 45 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 46 return receipt 47 } 48 49 func BenchmarkFilters(b *testing.B) { 50 var ( 51 db, _ = rawdb.NewLevelDBDatabase(b.TempDir(), 0, 0, "", false) 52 _, sys = newTestFilterSystem(b, db, Config{}) 53 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 54 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 55 addr2 = common.BytesToAddress([]byte("jeff")) 56 addr3 = common.BytesToAddress([]byte("ethereum")) 57 addr4 = common.BytesToAddress([]byte("random addresses please")) 58 59 gspec = &core.Genesis{ 60 Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}}, 61 BaseFee: big.NewInt(params.InitialBaseFee), 62 Config: params.TestChainConfig, 63 } 64 ) 65 defer db.Close() 66 _, chain, receipts := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 100010, func(i int, gen *core.BlockGen) { 67 switch i { 68 case 2403: 69 receipt := makeReceipt(addr1) 70 gen.AddUncheckedReceipt(receipt) 71 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 72 case 1034: 73 receipt := makeReceipt(addr2) 74 gen.AddUncheckedReceipt(receipt) 75 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 76 case 34: 77 receipt := makeReceipt(addr3) 78 gen.AddUncheckedReceipt(receipt) 79 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 80 case 99999: 81 receipt := makeReceipt(addr4) 82 gen.AddUncheckedReceipt(receipt) 83 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 84 } 85 }) 86 // The test txs are not properly signed, can't simply create a chain 87 // and then import blocks. TODO(rjl493456442) try to get rid of the 88 // manual database writes. 89 gspec.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults)) 90 91 for i, block := range chain { 92 rawdb.WriteBlock(db, block) 93 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 94 rawdb.WriteHeadBlockHash(db, block.Hash()) 95 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i]) 96 } 97 b.ResetTimer() 98 99 filter := sys.NewRangeFilter(0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) 100 101 for i := 0; i < b.N; i++ { 102 filter.begin = 0 103 logs, _ := filter.Logs(context.Background()) 104 if len(logs) != 4 { 105 b.Fatal("expected 4 logs, got", len(logs)) 106 } 107 } 108 } 109 110 func TestFilters(t *testing.T) { 111 var ( 112 db = rawdb.NewMemoryDatabase() 113 backend, sys = newTestFilterSystem(t, db, Config{}) 114 // Sender account 115 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 116 addr = crypto.PubkeyToAddress(key1.PublicKey) 117 signer = types.NewLondonSigner(big.NewInt(1)) 118 // Logging contract 119 contract = common.Address{0xfe} 120 contract2 = common.Address{0xff} 121 abiStr = `[{"inputs":[],"name":"log0","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"}],"name":"log1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"}],"name":"log2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"}],"name":"log3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"},{"internalType":"uint256","name":"t4","type":"uint256"}],"name":"log4","outputs":[],"stateMutability":"nonpayable","type":"function"}]` 122 /* 123 // SPDX-License-Identifier: GPL-3.0 124 pragma solidity >=0.7.0 <0.9.0; 125 126 contract Logger { 127 function log0() external { 128 assembly { 129 log0(0, 0) 130 } 131 } 132 133 function log1(uint t1) external { 134 assembly { 135 log1(0, 0, t1) 136 } 137 } 138 139 function log2(uint t1, uint t2) external { 140 assembly { 141 log2(0, 0, t1, t2) 142 } 143 } 144 145 function log3(uint t1, uint t2, uint t3) external { 146 assembly { 147 log3(0, 0, t1, t2, t3) 148 } 149 } 150 151 function log4(uint t1, uint t2, uint t3, uint t4) external { 152 assembly { 153 log4(0, 0, t1, t2, t3, t4) 154 } 155 } 156 } 157 */ 158 bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033") 159 160 hash1 = common.BytesToHash([]byte("topic1")) 161 hash2 = common.BytesToHash([]byte("topic2")) 162 hash3 = common.BytesToHash([]byte("topic3")) 163 hash4 = common.BytesToHash([]byte("topic4")) 164 hash5 = common.BytesToHash([]byte("topic5")) 165 166 gspec = &core.Genesis{ 167 Config: params.TestChainConfig, 168 Alloc: types.GenesisAlloc{ 169 addr: {Balance: big.NewInt(0).Mul(big.NewInt(100), big.NewInt(params.Ether))}, 170 contract: {Balance: big.NewInt(0), Code: bytecode}, 171 contract2: {Balance: big.NewInt(0), Code: bytecode}, 172 }, 173 BaseFee: big.NewInt(params.InitialBaseFee), 174 } 175 ) 176 177 contractABI, err := abi.JSON(strings.NewReader(abiStr)) 178 if err != nil { 179 t.Fatal(err) 180 } 181 182 // Hack: GenerateChainWithGenesis creates a new db. 183 // Commit the genesis manually and use GenerateChain. 184 _, err = gspec.Commit(db, triedb.NewDatabase(db, nil)) 185 if err != nil { 186 t.Fatal(err) 187 } 188 chain, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) { 189 switch i { 190 case 1: 191 data, err := contractABI.Pack("log1", hash1.Big()) 192 if err != nil { 193 t.Fatal(err) 194 } 195 tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ 196 Nonce: 0, 197 GasPrice: gen.BaseFee(), 198 Gas: 30000, 199 To: &contract, 200 Data: data, 201 }), signer, key1) 202 gen.AddTx(tx) 203 tx2, _ := types.SignTx(types.NewTx(&types.LegacyTx{ 204 Nonce: 1, 205 GasPrice: gen.BaseFee(), 206 Gas: 30000, 207 To: &contract2, 208 Data: data, 209 }), signer, key1) 210 gen.AddTx(tx2) 211 case 2: 212 data, err := contractABI.Pack("log2", hash2.Big(), hash1.Big()) 213 if err != nil { 214 t.Fatal(err) 215 } 216 tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ 217 Nonce: 2, 218 GasPrice: gen.BaseFee(), 219 Gas: 30000, 220 To: &contract, 221 Data: data, 222 }), signer, key1) 223 gen.AddTx(tx) 224 case 998: 225 data, err := contractABI.Pack("log1", hash3.Big()) 226 if err != nil { 227 t.Fatal(err) 228 } 229 tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ 230 Nonce: 3, 231 GasPrice: gen.BaseFee(), 232 Gas: 30000, 233 To: &contract2, 234 Data: data, 235 }), signer, key1) 236 gen.AddTx(tx) 237 case 999: 238 data, err := contractABI.Pack("log1", hash4.Big()) 239 if err != nil { 240 t.Fatal(err) 241 } 242 tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ 243 Nonce: 4, 244 GasPrice: gen.BaseFee(), 245 Gas: 30000, 246 To: &contract, 247 Data: data, 248 }), signer, key1) 249 gen.AddTx(tx) 250 } 251 }) 252 var l uint64 253 bc, err := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l) 254 if err != nil { 255 t.Fatal(err) 256 } 257 _, err = bc.InsertChain(chain) 258 if err != nil { 259 t.Fatal(err) 260 } 261 262 // Set block 998 as Finalized (-3) 263 bc.SetFinalized(chain[998].Header()) 264 265 // Generate pending block 266 pchain, preceipts := core.GenerateChain(gspec.Config, chain[len(chain)-1], ethash.NewFaker(), db, 1, func(i int, gen *core.BlockGen) { 267 data, err := contractABI.Pack("log1", hash5.Big()) 268 if err != nil { 269 t.Fatal(err) 270 } 271 tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ 272 Nonce: 5, 273 GasPrice: gen.BaseFee(), 274 Gas: 30000, 275 To: &contract, 276 Data: data, 277 }), signer, key1) 278 gen.AddTx(tx) 279 }) 280 backend.setPending(pchain[0], preceipts[0]) 281 282 for i, tc := range []struct { 283 f *Filter 284 want string 285 err string 286 }{ 287 { 288 f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil), 289 want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`, 290 }, 291 { 292 f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}), 293 want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`, 294 }, 295 { 296 f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}), 297 }, 298 { 299 f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}), 300 want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`, 301 }, 302 { 303 f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}), 304 want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`, 305 }, 306 { 307 f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}), 308 want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`, 309 }, 310 { 311 f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}), 312 }, 313 { 314 f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil), 315 }, 316 { 317 f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}), 318 }, 319 { 320 f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), 321 want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`, 322 }, 323 { 324 f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), 325 want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`, 326 }, 327 { 328 f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), 329 want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`, 330 }, 331 { 332 f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), 333 }, 334 { 335 f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), 336 err: "safe header not found", 337 }, 338 { 339 f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), 340 err: "safe header not found", 341 }, 342 { 343 f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), 344 err: "safe header not found", 345 }, 346 { 347 f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), 348 err: errPendingLogsUnsupported.Error(), 349 }, 350 { 351 f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), 352 err: errPendingLogsUnsupported.Error(), 353 }, 354 { 355 f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), 356 err: errPendingLogsUnsupported.Error(), 357 }, 358 } { 359 logs, err := tc.f.Logs(context.Background()) 360 if err == nil && tc.err != "" { 361 t.Fatalf("test %d, expected error %q, got nil", i, tc.err) 362 } else if err != nil && err.Error() != tc.err { 363 t.Fatalf("test %d, expected error %q, got %q", i, tc.err, err.Error()) 364 } 365 if tc.want == "" && len(logs) == 0 { 366 continue 367 } 368 have, err := json.Marshal(logs) 369 if err != nil { 370 t.Fatal(err) 371 } 372 if string(have) != tc.want { 373 t.Fatalf("test %d, have:\n%s\nwant:\n%s", i, have, tc.want) 374 } 375 } 376 377 t.Run("timeout", func(t *testing.T) { 378 f := sys.NewRangeFilter(0, rpc.LatestBlockNumber.Int64(), nil, nil) 379 ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Hour)) 380 defer cancel() 381 _, err := f.Logs(ctx) 382 if err == nil { 383 t.Fatal("expected error") 384 } 385 if err != context.DeadlineExceeded { 386 t.Fatalf("expected context.DeadlineExceeded, got %v", err) 387 } 388 }) 389 }