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