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