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  }