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