github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/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/wanchain/go-wanchain/common"
    27  	"github.com/wanchain/go-wanchain/consensus/ethash"
    28  	"github.com/wanchain/go-wanchain/core"
    29  	"github.com/wanchain/go-wanchain/core/types"
    30  	"github.com/wanchain/go-wanchain/core/vm"
    31  	"github.com/wanchain/go-wanchain/crypto"
    32  	"github.com/wanchain/go-wanchain/ethdb"
    33  	"github.com/wanchain/go-wanchain/event"
    34  )
    35  
    36  func makeReceipt(addr common.Address) *types.Receipt {
    37  	receipt := types.NewReceipt(nil, false, 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 BenchmarkFilters(b *testing.B) {
    46  	dir, err := ioutil.TempDir("", "filtertest")
    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  		engine     = ethash.NewFaker(db)
    55  		mux        = new(event.TypeMux)
    56  		txFeed     = new(event.Feed)
    57  		rmLogsFeed = new(event.Feed)
    58  		logsFeed   = new(event.Feed)
    59  		chainFeed  = new(event.Feed)
    60  		backend    = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
    61  		key1, _    = crypto.HexToECDSA("f1572f76b75b40a7da72d6f2ee7fda3d1189c2d28f0a2f096347055abe344d7f")
    62  		addr1      = crypto.PubkeyToAddress(key1.PublicKey)
    63  		addr2      = common.BytesToAddress([]byte("jeff"))
    64  		addr3      = common.BytesToAddress([]byte("wanchain"))
    65  		addr4      = common.BytesToAddress([]byte("random addresses please"))
    66  	)
    67  	defer db.Close()
    68  
    69  	// genesis := core.GenesisBlockForTesting(db, addr1, big.NewInt(1000000))
    70  
    71  	// create a genesis block
    72  	gspec := core.DefaultPPOWTestingGenesisBlock()
    73  	genesis := gspec.MustCommit(db)
    74  
    75  	blockChain, _ := core.NewBlockChain(db, gspec.Config, engine, vm.Config{})
    76  	defer blockChain.Stop()
    77  
    78  	chainEnv := core.NewChainEnv(gspec.Config, gspec, engine, blockChain, db)
    79  
    80  	chain, receipts := chainEnv.GenerateChain(genesis, 100010, func(i int, gen *core.BlockGen) {
    81  		switch i {
    82  		case 2403:
    83  			receipt := makeReceipt(addr1)
    84  			gen.AddUncheckedReceipt(receipt)
    85  		case 1034:
    86  			receipt := makeReceipt(addr2)
    87  			gen.AddUncheckedReceipt(receipt)
    88  		case 34:
    89  			receipt := makeReceipt(addr3)
    90  			gen.AddUncheckedReceipt(receipt)
    91  		case 99999:
    92  			receipt := makeReceipt(addr4)
    93  			gen.AddUncheckedReceipt(receipt)
    94  
    95  		}
    96  	})
    97  	for i, block := range chain {
    98  		core.WriteBlock(db, block)
    99  		if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
   100  			b.Fatalf("failed to insert block number: %v", err)
   101  		}
   102  		if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
   103  			b.Fatalf("failed to insert block number: %v", err)
   104  		}
   105  		if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
   106  			b.Fatal("error writing block receipts:", err)
   107  		}
   108  	}
   109  	b.ResetTimer()
   110  
   111  	filter := New(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil)
   112  
   113  	for i := 0; i < b.N; i++ {
   114  		logs, _ := filter.Logs(context.Background())
   115  		if len(logs) != 4 {
   116  			b.Fatal("expected 4 logs, got", len(logs))
   117  		}
   118  	}
   119  }
   120  
   121  func TestFilters(t *testing.T) {
   122  	dir, err := ioutil.TempDir("", "filtertest")
   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  		engine     = ethash.NewFaker(db)
   131  		mux        = new(event.TypeMux)
   132  		txFeed     = new(event.Feed)
   133  		rmLogsFeed = new(event.Feed)
   134  		logsFeed   = new(event.Feed)
   135  		chainFeed  = new(event.Feed)
   136  		backend    = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
   137  		key1, _    = crypto.HexToECDSA("f1572f76b75b40a7da72d6f2ee7fda3d1189c2d28f0a2f096347055abe344d7f")
   138  		addr       = crypto.PubkeyToAddress(key1.PublicKey)
   139  
   140  		hash1 = common.BytesToHash([]byte("topic1"))
   141  		hash2 = common.BytesToHash([]byte("topic2"))
   142  		hash3 = common.BytesToHash([]byte("topic3"))
   143  		hash4 = common.BytesToHash([]byte("topic4"))
   144  	)
   145  	defer db.Close()
   146  
   147  	// create a genesis block
   148  	gspec := core.DefaultPPOWTestingGenesisBlock()
   149  	genesis := gspec.MustCommit(db)
   150  
   151  	blockChain, _ := core.NewBlockChain(db, gspec.Config, engine, vm.Config{})
   152  	defer blockChain.Stop()
   153  
   154  	chainEnv := core.NewChainEnv(gspec.Config, gspec, engine, blockChain, db)
   155  
   156  	chain, receipts := chainEnv.GenerateChain(genesis, 1000, func(i int, gen *core.BlockGen) {
   157  		switch i {
   158  		case 1:
   159  			receipt := types.NewReceipt(nil, false, new(big.Int))
   160  			receipt.Logs = []*types.Log{
   161  				{
   162  					Address: addr,
   163  					Topics:  []common.Hash{hash1},
   164  				},
   165  			}
   166  			gen.AddUncheckedReceipt(receipt)
   167  		case 2:
   168  			receipt := types.NewReceipt(nil, false, new(big.Int))
   169  			receipt.Logs = []*types.Log{
   170  				{
   171  					Address: addr,
   172  					Topics:  []common.Hash{hash2},
   173  				},
   174  			}
   175  			gen.AddUncheckedReceipt(receipt)
   176  		case 998:
   177  			receipt := types.NewReceipt(nil, false, new(big.Int))
   178  			receipt.Logs = []*types.Log{
   179  				{
   180  					Address: addr,
   181  					Topics:  []common.Hash{hash3},
   182  				},
   183  			}
   184  			gen.AddUncheckedReceipt(receipt)
   185  		case 999:
   186  			receipt := types.NewReceipt(nil, false, new(big.Int))
   187  			receipt.Logs = []*types.Log{
   188  				{
   189  					Address: addr,
   190  					Topics:  []common.Hash{hash4},
   191  				},
   192  			}
   193  			gen.AddUncheckedReceipt(receipt)
   194  		}
   195  	})
   196  	for i, block := range chain {
   197  		core.WriteBlock(db, block)
   198  		if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
   199  			t.Fatalf("failed to insert block number: %v", err)
   200  		}
   201  		if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
   202  			t.Fatalf("failed to insert block number: %v", err)
   203  		}
   204  		if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
   205  			t.Fatal("error writing block receipts:", err)
   206  		}
   207  	}
   208  
   209  	filter := New(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
   210  
   211  	logs, _ := filter.Logs(context.Background())
   212  	if len(logs) != 4 {
   213  		t.Error("expected 4 log, got", len(logs))
   214  	}
   215  
   216  	// for _, log := range logs {
   217  	// 	fmt.Println("log: ", log.String())
   218  	// }
   219  
   220  	filter = New(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}})
   221  	logs, _ = filter.Logs(context.Background())
   222  	if len(logs) != 1 {
   223  		t.Error("expected 1 log, got", len(logs))
   224  	}
   225  	if len(logs) > 0 && logs[0].Topics[0] != hash3 {
   226  		t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
   227  	}
   228  
   229  	filter = New(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}})
   230  	logs, _ = filter.Logs(context.Background())
   231  	if len(logs) != 1 {
   232  		t.Error("expected 1 log, got", len(logs))
   233  	}
   234  	if len(logs) > 0 && logs[0].Topics[0] != hash3 {
   235  		t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
   236  	}
   237  
   238  	filter = New(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}})
   239  
   240  	logs, _ = filter.Logs(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, 0, -1, nil, [][]common.Hash{{failHash}})
   247  
   248  	logs, _ = filter.Logs(context.Background())
   249  	if len(logs) != 0 {
   250  		t.Error("expected 0 log, got", len(logs))
   251  	}
   252  
   253  	failAddr := common.BytesToAddress([]byte("failmenow"))
   254  	filter = New(backend, 0, -1, []common.Address{failAddr}, nil)
   255  
   256  	logs, _ = filter.Logs(context.Background())
   257  	if len(logs) != 0 {
   258  		t.Error("expected 0 log, got", len(logs))
   259  	}
   260  
   261  	filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}})
   262  
   263  	logs, _ = filter.Logs(context.Background())
   264  	if len(logs) != 0 {
   265  		t.Error("expected 0 log, got", len(logs))
   266  	}
   267  }