github.com/carter-ya/go-ethereum@v0.0.0-20230628080049-d2309be3983b/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  	"math/big"
    22  	"testing"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/consensus/ethash"
    26  	"github.com/ethereum/go-ethereum/core"
    27  	"github.com/ethereum/go-ethereum/core/rawdb"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/crypto"
    30  	"github.com/ethereum/go-ethereum/params"
    31  )
    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  
    42  func BenchmarkFilters(b *testing.B) {
    43  	var (
    44  		db, _   = rawdb.NewLevelDBDatabase(b.TempDir(), 0, 0, "", false)
    45  		_, sys  = newTestFilterSystem(b, db, Config{})
    46  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    47  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
    48  		addr2   = common.BytesToAddress([]byte("jeff"))
    49  		addr3   = common.BytesToAddress([]byte("ethereum"))
    50  		addr4   = common.BytesToAddress([]byte("random addresses please"))
    51  
    52  		gspec = &core.Genesis{
    53  			Alloc:   core.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}},
    54  			BaseFee: big.NewInt(params.InitialBaseFee),
    55  		}
    56  	)
    57  	defer db.Close()
    58  
    59  	_, chain, receipts := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 100010, func(i int, gen *core.BlockGen) {
    60  		switch i {
    61  		case 2403:
    62  			receipt := makeReceipt(addr1)
    63  			gen.AddUncheckedReceipt(receipt)
    64  			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
    65  		case 1034:
    66  			receipt := makeReceipt(addr2)
    67  			gen.AddUncheckedReceipt(receipt)
    68  			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
    69  		case 34:
    70  			receipt := makeReceipt(addr3)
    71  			gen.AddUncheckedReceipt(receipt)
    72  			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
    73  		case 99999:
    74  			receipt := makeReceipt(addr4)
    75  			gen.AddUncheckedReceipt(receipt)
    76  			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
    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  
    87  	filter := sys.NewRangeFilter(0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil)
    88  
    89  	for i := 0; i < b.N; i++ {
    90  		logs, _ := filter.Logs(context.Background())
    91  		if len(logs) != 4 {
    92  			b.Fatal("expected 4 logs, got", len(logs))
    93  		}
    94  	}
    95  }
    96  
    97  func TestFilters(t *testing.T) {
    98  	var (
    99  		db, _   = rawdb.NewLevelDBDatabase(t.TempDir(), 0, 0, "", false)
   100  		_, sys  = newTestFilterSystem(t, db, Config{})
   101  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   102  		addr    = crypto.PubkeyToAddress(key1.PublicKey)
   103  
   104  		hash1 = common.BytesToHash([]byte("topic1"))
   105  		hash2 = common.BytesToHash([]byte("topic2"))
   106  		hash3 = common.BytesToHash([]byte("topic3"))
   107  		hash4 = common.BytesToHash([]byte("topic4"))
   108  
   109  		gspec = &core.Genesis{
   110  			Config:  params.TestChainConfig,
   111  			Alloc:   core.GenesisAlloc{addr: {Balance: big.NewInt(1000000)}},
   112  			BaseFee: big.NewInt(params.InitialBaseFee),
   113  		}
   114  	)
   115  	defer db.Close()
   116  
   117  	_, chain, receipts := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 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  			gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, gen.BaseFee(), nil))
   129  		case 2:
   130  			receipt := types.NewReceipt(nil, false, 0)
   131  			receipt.Logs = []*types.Log{
   132  				{
   133  					Address: addr,
   134  					Topics:  []common.Hash{hash2},
   135  				},
   136  			}
   137  			gen.AddUncheckedReceipt(receipt)
   138  			gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, gen.BaseFee(), nil))
   139  
   140  		case 998:
   141  			receipt := types.NewReceipt(nil, false, 0)
   142  			receipt.Logs = []*types.Log{
   143  				{
   144  					Address: addr,
   145  					Topics:  []common.Hash{hash3},
   146  				},
   147  			}
   148  			gen.AddUncheckedReceipt(receipt)
   149  			gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, gen.BaseFee(), nil))
   150  		case 999:
   151  			receipt := types.NewReceipt(nil, false, 0)
   152  			receipt.Logs = []*types.Log{
   153  				{
   154  					Address: addr,
   155  					Topics:  []common.Hash{hash4},
   156  				},
   157  			}
   158  			gen.AddUncheckedReceipt(receipt)
   159  			gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
   160  		}
   161  	})
   162  	// The test txs are not properly signed, can't simply create a chain
   163  	// and then import blocks. TODO(rjl493456442) try to get rid of the
   164  	// manual database writes.
   165  	gspec.MustCommit(db)
   166  	for i, block := range chain {
   167  		rawdb.WriteBlock(db, block)
   168  		rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
   169  		rawdb.WriteHeadBlockHash(db, block.Hash())
   170  		rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i])
   171  	}
   172  
   173  	filter := sys.NewRangeFilter(0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
   174  
   175  	logs, _ := filter.Logs(context.Background())
   176  	if len(logs) != 4 {
   177  		t.Error("expected 4 log, got", len(logs))
   178  	}
   179  
   180  	filter = sys.NewRangeFilter(900, 999, []common.Address{addr}, [][]common.Hash{{hash3}})
   181  	logs, _ = filter.Logs(context.Background())
   182  	if len(logs) != 1 {
   183  		t.Error("expected 1 log, got", len(logs))
   184  	}
   185  	if len(logs) > 0 && logs[0].Topics[0] != hash3 {
   186  		t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
   187  	}
   188  
   189  	filter = sys.NewRangeFilter(990, -1, []common.Address{addr}, [][]common.Hash{{hash3}})
   190  	logs, _ = filter.Logs(context.Background())
   191  	if len(logs) != 1 {
   192  		t.Error("expected 1 log, got", len(logs))
   193  	}
   194  	if len(logs) > 0 && logs[0].Topics[0] != hash3 {
   195  		t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
   196  	}
   197  
   198  	filter = sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}})
   199  
   200  	logs, _ = filter.Logs(context.Background())
   201  	if len(logs) != 2 {
   202  		t.Error("expected 2 log, got", len(logs))
   203  	}
   204  
   205  	failHash := common.BytesToHash([]byte("fail"))
   206  	filter = sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{failHash}})
   207  
   208  	logs, _ = filter.Logs(context.Background())
   209  	if len(logs) != 0 {
   210  		t.Error("expected 0 log, got", len(logs))
   211  	}
   212  
   213  	failAddr := common.BytesToAddress([]byte("failmenow"))
   214  	filter = sys.NewRangeFilter(0, -1, []common.Address{failAddr}, nil)
   215  
   216  	logs, _ = filter.Logs(context.Background())
   217  	if len(logs) != 0 {
   218  		t.Error("expected 0 log, got", len(logs))
   219  	}
   220  
   221  	filter = sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{failHash}, {hash1}})
   222  
   223  	logs, _ = filter.Logs(context.Background())
   224  	if len(logs) != 0 {
   225  		t.Error("expected 0 log, got", len(logs))
   226  	}
   227  }