github.com/myafeier/go-ethereum@v1.6.8-0.20170719123245-3e0dbe0eaa72/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  	"io/ioutil"
    22  	"math/big"
    23  	"os"
    24  	"testing"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/core"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/crypto"
    30  	"github.com/ethereum/go-ethereum/ethdb"
    31  	"github.com/ethereum/go-ethereum/event"
    32  	"github.com/ethereum/go-ethereum/params"
    33  )
    34  
    35  func makeReceipt(addr common.Address) *types.Receipt {
    36  	receipt := types.NewReceipt(nil, new(big.Int))
    37  	receipt.Logs = []*types.Log{
    38  		{Address: addr},
    39  	}
    40  	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
    41  	return receipt
    42  }
    43  
    44  func BenchmarkMipmaps(b *testing.B) {
    45  	dir, err := ioutil.TempDir("", "mipmap")
    46  	if err != nil {
    47  		b.Fatal(err)
    48  	}
    49  	defer os.RemoveAll(dir)
    50  
    51  	var (
    52  		db, _   = ethdb.NewLDBDatabase(dir, 0, 0)
    53  		mux     = new(event.TypeMux)
    54  		backend = &testBackend{mux, db}
    55  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    56  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
    57  		addr2   = common.BytesToAddress([]byte("jeff"))
    58  		addr3   = common.BytesToAddress([]byte("ethereum"))
    59  		addr4   = common.BytesToAddress([]byte("random addresses please"))
    60  	)
    61  	defer db.Close()
    62  
    63  	genesis := core.GenesisBlockForTesting(db, addr1, big.NewInt(1000000))
    64  	chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 100010, func(i int, gen *core.BlockGen) {
    65  		var receipts types.Receipts
    66  		switch i {
    67  		case 2403:
    68  			receipt := makeReceipt(addr1)
    69  			receipts = types.Receipts{receipt}
    70  			gen.AddUncheckedReceipt(receipt)
    71  		case 1034:
    72  			receipt := makeReceipt(addr2)
    73  			receipts = types.Receipts{receipt}
    74  			gen.AddUncheckedReceipt(receipt)
    75  		case 34:
    76  			receipt := makeReceipt(addr3)
    77  			receipts = types.Receipts{receipt}
    78  			gen.AddUncheckedReceipt(receipt)
    79  		case 99999:
    80  			receipt := makeReceipt(addr4)
    81  			receipts = types.Receipts{receipt}
    82  			gen.AddUncheckedReceipt(receipt)
    83  
    84  		}
    85  		core.WriteMipmapBloom(db, uint64(i+1), receipts)
    86  	})
    87  	for i, block := range chain {
    88  		core.WriteBlock(db, block)
    89  		if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
    90  			b.Fatalf("failed to insert block number: %v", err)
    91  		}
    92  		if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
    93  			b.Fatalf("failed to insert block number: %v", err)
    94  		}
    95  		if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
    96  			b.Fatal("error writing block receipts:", err)
    97  		}
    98  	}
    99  	b.ResetTimer()
   100  
   101  	filter := New(backend, true)
   102  	filter.SetAddresses([]common.Address{addr1, addr2, addr3, addr4})
   103  	filter.SetBeginBlock(0)
   104  	filter.SetEndBlock(-1)
   105  
   106  	for i := 0; i < b.N; i++ {
   107  		logs, _ := filter.Find(context.Background())
   108  		if len(logs) != 4 {
   109  			b.Fatal("expected 4 logs, got", len(logs))
   110  		}
   111  	}
   112  }
   113  
   114  func TestFilters(t *testing.T) {
   115  	dir, err := ioutil.TempDir("", "mipmap")
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  	defer os.RemoveAll(dir)
   120  
   121  	var (
   122  		db, _   = ethdb.NewLDBDatabase(dir, 0, 0)
   123  		mux     = new(event.TypeMux)
   124  		backend = &testBackend{mux, db}
   125  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   126  		addr    = crypto.PubkeyToAddress(key1.PublicKey)
   127  
   128  		hash1 = common.BytesToHash([]byte("topic1"))
   129  		hash2 = common.BytesToHash([]byte("topic2"))
   130  		hash3 = common.BytesToHash([]byte("topic3"))
   131  		hash4 = common.BytesToHash([]byte("topic4"))
   132  	)
   133  	defer db.Close()
   134  
   135  	genesis := core.GenesisBlockForTesting(db, addr, big.NewInt(1000000))
   136  	chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 1000, func(i int, gen *core.BlockGen) {
   137  		var receipts types.Receipts
   138  		switch i {
   139  		case 1:
   140  			receipt := types.NewReceipt(nil, new(big.Int))
   141  			receipt.Logs = []*types.Log{
   142  				{
   143  					Address: addr,
   144  					Topics:  []common.Hash{hash1},
   145  				},
   146  			}
   147  			gen.AddUncheckedReceipt(receipt)
   148  			receipts = types.Receipts{receipt}
   149  		case 2:
   150  			receipt := types.NewReceipt(nil, new(big.Int))
   151  			receipt.Logs = []*types.Log{
   152  				{
   153  					Address: addr,
   154  					Topics:  []common.Hash{hash2},
   155  				},
   156  			}
   157  			gen.AddUncheckedReceipt(receipt)
   158  			receipts = types.Receipts{receipt}
   159  		case 998:
   160  			receipt := types.NewReceipt(nil, new(big.Int))
   161  			receipt.Logs = []*types.Log{
   162  				{
   163  					Address: addr,
   164  					Topics:  []common.Hash{hash3},
   165  				},
   166  			}
   167  			gen.AddUncheckedReceipt(receipt)
   168  			receipts = types.Receipts{receipt}
   169  		case 999:
   170  			receipt := types.NewReceipt(nil, new(big.Int))
   171  			receipt.Logs = []*types.Log{
   172  				{
   173  					Address: addr,
   174  					Topics:  []common.Hash{hash4},
   175  				},
   176  			}
   177  			gen.AddUncheckedReceipt(receipt)
   178  			receipts = types.Receipts{receipt}
   179  		}
   180  		// i is used as block number for the writes but since the i
   181  		// starts at 0 and block 0 (genesis) is already present increment
   182  		// by one
   183  		core.WriteMipmapBloom(db, uint64(i+1), receipts)
   184  	})
   185  	for i, block := range chain {
   186  		core.WriteBlock(db, block)
   187  		if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
   188  			t.Fatalf("failed to insert block number: %v", err)
   189  		}
   190  		if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
   191  			t.Fatalf("failed to insert block number: %v", err)
   192  		}
   193  		if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
   194  			t.Fatal("error writing block receipts:", err)
   195  		}
   196  	}
   197  
   198  	filter := New(backend, true)
   199  	filter.SetAddresses([]common.Address{addr})
   200  	filter.SetTopics([][]common.Hash{{hash1, hash2, hash3, hash4}})
   201  	filter.SetBeginBlock(0)
   202  	filter.SetEndBlock(-1)
   203  
   204  	logs, _ := filter.Find(context.Background())
   205  	if len(logs) != 4 {
   206  		t.Error("expected 4 log, got", len(logs))
   207  	}
   208  
   209  	filter = New(backend, true)
   210  	filter.SetAddresses([]common.Address{addr})
   211  	filter.SetTopics([][]common.Hash{{hash3}})
   212  	filter.SetBeginBlock(900)
   213  	filter.SetEndBlock(999)
   214  	logs, _ = filter.Find(context.Background())
   215  	if len(logs) != 1 {
   216  		t.Error("expected 1 log, got", len(logs))
   217  	}
   218  	if len(logs) > 0 && logs[0].Topics[0] != hash3 {
   219  		t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
   220  	}
   221  
   222  	filter = New(backend, true)
   223  	filter.SetAddresses([]common.Address{addr})
   224  	filter.SetTopics([][]common.Hash{{hash3}})
   225  	filter.SetBeginBlock(990)
   226  	filter.SetEndBlock(-1)
   227  	logs, _ = filter.Find(context.Background())
   228  	if len(logs) != 1 {
   229  		t.Error("expected 1 log, got", len(logs))
   230  	}
   231  	if len(logs) > 0 && logs[0].Topics[0] != hash3 {
   232  		t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
   233  	}
   234  
   235  	filter = New(backend, true)
   236  	filter.SetTopics([][]common.Hash{{hash1, hash2}})
   237  	filter.SetBeginBlock(1)
   238  	filter.SetEndBlock(10)
   239  
   240  	logs, _ = filter.Find(context.Background())
   241  	if len(logs) != 2 {
   242  		t.Error("expected 2 log, got", len(logs))
   243  	}
   244  
   245  	failHash := common.BytesToHash([]byte("fail"))
   246  	filter = New(backend, true)
   247  	filter.SetTopics([][]common.Hash{{failHash}})
   248  	filter.SetBeginBlock(0)
   249  	filter.SetEndBlock(-1)
   250  
   251  	logs, _ = filter.Find(context.Background())
   252  	if len(logs) != 0 {
   253  		t.Error("expected 0 log, got", len(logs))
   254  	}
   255  
   256  	failAddr := common.BytesToAddress([]byte("failmenow"))
   257  	filter = New(backend, true)
   258  	filter.SetAddresses([]common.Address{failAddr})
   259  	filter.SetBeginBlock(0)
   260  	filter.SetEndBlock(-1)
   261  
   262  	logs, _ = filter.Find(context.Background())
   263  	if len(logs) != 0 {
   264  		t.Error("expected 0 log, got", len(logs))
   265  	}
   266  
   267  	filter = New(backend, true)
   268  	filter.SetTopics([][]common.Hash{{failHash}, {hash1}})
   269  	filter.SetBeginBlock(0)
   270  	filter.SetEndBlock(-1)
   271  
   272  	logs, _ = filter.Find(context.Background())
   273  	if len(logs) != 0 {
   274  		t.Error("expected 0 log, got", len(logs))
   275  	}
   276  }