github.com/MetalBlockchain/subnet-evm@v0.4.9/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 "math/big" 32 "testing" 33 34 "github.com/MetalBlockchain/subnet-evm/consensus/dummy" 35 "github.com/MetalBlockchain/subnet-evm/core" 36 "github.com/MetalBlockchain/subnet-evm/core/rawdb" 37 "github.com/MetalBlockchain/subnet-evm/core/types" 38 "github.com/MetalBlockchain/subnet-evm/params" 39 "github.com/ethereum/go-ethereum/common" 40 "github.com/ethereum/go-ethereum/crypto" 41 "github.com/stretchr/testify/require" 42 ) 43 44 func makeReceipt(addr common.Address) *types.Receipt { 45 receipt := types.NewReceipt(nil, false, 0) 46 receipt.Logs = []*types.Log{ 47 {Address: addr}, 48 } 49 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 50 return receipt 51 } 52 53 func BenchmarkFilters(b *testing.B) { 54 dir := b.TempDir() 55 56 var ( 57 db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false) 58 _, sys = newTestFilterSystem(b, db, Config{}) 59 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 60 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 61 addr2 = common.BytesToAddress([]byte("jeff")) 62 addr3 = common.BytesToAddress([]byte("ethereum")) 63 addr4 = common.BytesToAddress([]byte("random addresses please")) 64 65 gspec = core.Genesis{ 66 Alloc: core.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}}, 67 BaseFee: big.NewInt(1), 68 Config: params.TestChainConfig, 69 } 70 genesis = gspec.ToBlock(db) 71 ) 72 defer db.Close() 73 74 gspec.MustCommit(db) 75 76 chain, receipts, err := core.GenerateChain(gspec.Config, genesis, dummy.NewFaker(), db, 100010, 10, func(i int, gen *core.BlockGen) { 77 switch i { 78 case 2403: 79 receipt := makeReceipt(addr1) 80 gen.AddUncheckedReceipt(receipt) 81 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 82 case 1034: 83 receipt := makeReceipt(addr2) 84 gen.AddUncheckedReceipt(receipt) 85 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 86 case 34: 87 receipt := makeReceipt(addr3) 88 gen.AddUncheckedReceipt(receipt) 89 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 90 case 99999: 91 receipt := makeReceipt(addr4) 92 gen.AddUncheckedReceipt(receipt) 93 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 94 } 95 }) 96 require.NoError(b, err) 97 for i, block := range chain { 98 rawdb.WriteBlock(db, block) 99 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 100 rawdb.WriteHeadBlockHash(db, block.Hash()) 101 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i]) 102 } 103 b.ResetTimer() 104 105 filter, err := sys.NewRangeFilter(0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) 106 require.NoError(b, err) 107 108 for i := 0; i < b.N; i++ { 109 logs, _ := filter.Logs(context.Background()) 110 if len(logs) != 4 { 111 b.Fatal("expected 4 logs, got", len(logs)) 112 } 113 } 114 } 115 116 func TestFilters(t *testing.T) { 117 dir := t.TempDir() 118 119 var ( 120 db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false) 121 _, sys = newTestFilterSystem(t, db, Config{}) 122 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 123 addr = crypto.PubkeyToAddress(key1.PublicKey) 124 125 hash1 = common.BytesToHash([]byte("topic1")) 126 hash2 = common.BytesToHash([]byte("topic2")) 127 hash3 = common.BytesToHash([]byte("topic3")) 128 hash4 = common.BytesToHash([]byte("topic4")) 129 130 gspec = core.Genesis{ 131 Alloc: core.GenesisAlloc{addr: {Balance: big.NewInt(1000000)}}, 132 BaseFee: big.NewInt(1), 133 Config: params.TestChainConfig, 134 } 135 genesis = gspec.ToBlock(db) 136 ) 137 defer db.Close() 138 139 gspec.MustCommit(db) 140 141 chain, receipts, err := core.GenerateChain(gspec.Config, genesis, dummy.NewFaker(), db, 1000, 10, func(i int, gen *core.BlockGen) { 142 switch i { 143 case 1: 144 receipt := types.NewReceipt(nil, false, 0) 145 receipt.Logs = []*types.Log{ 146 { 147 Address: addr, 148 Topics: []common.Hash{hash1}, 149 }, 150 } 151 gen.AddUncheckedReceipt(receipt) 152 gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, gen.BaseFee(), nil)) 153 case 2: 154 receipt := types.NewReceipt(nil, false, 0) 155 receipt.Logs = []*types.Log{ 156 { 157 Address: addr, 158 Topics: []common.Hash{hash2}, 159 }, 160 } 161 gen.AddUncheckedReceipt(receipt) 162 gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, gen.BaseFee(), nil)) 163 164 case 998: 165 receipt := types.NewReceipt(nil, false, 0) 166 receipt.Logs = []*types.Log{ 167 { 168 Address: addr, 169 Topics: []common.Hash{hash3}, 170 }, 171 } 172 gen.AddUncheckedReceipt(receipt) 173 gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, gen.BaseFee(), nil)) 174 case 999: 175 receipt := types.NewReceipt(nil, false, 0) 176 receipt.Logs = []*types.Log{ 177 { 178 Address: addr, 179 Topics: []common.Hash{hash4}, 180 }, 181 } 182 gen.AddUncheckedReceipt(receipt) 183 gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil)) 184 } 185 }) 186 require.NoError(t, err) 187 for i, block := range chain { 188 rawdb.WriteBlock(db, block) 189 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 190 rawdb.WriteHeadBlockHash(db, block.Hash()) 191 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i]) 192 } 193 194 filter, err := sys.NewRangeFilter(0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}) 195 require.NoError(t, err) 196 197 logs, _ := filter.Logs(context.Background()) 198 if len(logs) != 4 { 199 t.Error("expected 4 log, got", len(logs)) 200 } 201 202 filter, err = sys.NewRangeFilter(900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}) 203 require.NoError(t, err) 204 205 logs, _ = filter.Logs(context.Background()) 206 if len(logs) != 1 { 207 t.Error("expected 1 log, got", len(logs)) 208 } 209 if len(logs) > 0 && logs[0].Topics[0] != hash3 { 210 t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) 211 } 212 213 filter, err = sys.NewRangeFilter(990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}) 214 require.NoError(t, err) 215 216 logs, _ = filter.Logs(context.Background()) 217 if len(logs) != 1 { 218 t.Error("expected 1 log, got", len(logs)) 219 } 220 if len(logs) > 0 && logs[0].Topics[0] != hash3 { 221 t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) 222 } 223 224 filter, err = sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}) 225 require.NoError(t, err) 226 227 logs, _ = filter.Logs(context.Background()) 228 if len(logs) != 2 { 229 t.Error("expected 2 log, got", len(logs)) 230 } 231 232 failHash := common.BytesToHash([]byte("fail")) 233 filter, err = sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{failHash}}) 234 require.NoError(t, err) 235 236 logs, _ = filter.Logs(context.Background()) 237 if len(logs) != 0 { 238 t.Error("expected 0 log, got", len(logs)) 239 } 240 241 failAddr := common.BytesToAddress([]byte("failmenow")) 242 filter, err = sys.NewRangeFilter(0, -1, []common.Address{failAddr}, nil) 243 require.NoError(t, err) 244 245 logs, _ = filter.Logs(context.Background()) 246 if len(logs) != 0 { 247 t.Error("expected 0 log, got", len(logs)) 248 } 249 250 filter, err = sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{failHash}, {hash1}}) 251 require.NoError(t, err) 252 253 logs, _ = filter.Logs(context.Background()) 254 if len(logs) != 0 { 255 t.Error("expected 0 log, got", len(logs)) 256 } 257 }