aboutsummaryrefslogblamecommitdiffstats
path: root/eth/filters/filter_test.go
blob: 11235e95a7543617393caac121ae4730443199d9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                                                  


               
                 
                   






                                                    

                                                
                                               
                                                


                                                      
                                                             

                                    
         



                                                                  

                                                    




                               
             





                                                            
                                                                                              




                                                                                                                  
         
                        
 
                                                                              
                                                                                                                            


                                                     

                                                        
                                                     
                                                        

                                                     
                                                        

                                                     
                                                        

                 
          
                                     






                                                                                                    
                                                                                                                 


                                                                     

                      
                                                                                        

                                  
                                                            
                                   
                                                                  


                 

                                
                                                    





                               





                                                            
                                                                                              

                                                                                                                  







                                                            
                                                                             
                                                                                                                          

                          
                                                                             

                                                    


                                                                      
                         
                                                        
                       
                                                                             

                                                    


                                                                      
                         
                                                        
                         
                                                                             

                                                    


                                                                      
                         
                                                        
                         
                                                                             

                                                    


                                                                      
                         
                                                        
                 
          
                                     






                                                                                                    
                                                                                                                 



                                                                     
                                                                                                            
 
                                                    



                                                         
                                                                                         
                                                   






                                                                                                
                                                                                        
                                                   






                                                                                                
                                                                          
 
                                                   




                                                         
                                                                      
 
                                                   




                                                              
                                                                     
 
                                                   



                                                         
                                                                               
 
                                                   



                                                         
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package filters

import (
    "context"
    "io/ioutil"
    "math/big"
    "os"
    "testing"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/ethdb"
    "github.com/ethereum/go-ethereum/event"
    "github.com/ethereum/go-ethereum/params"
)

func makeReceipt(addr common.Address) *types.Receipt {
    receipt := types.NewReceipt(nil, false, new(big.Int))
    receipt.Logs = []*types.Log{
        {Address: addr},
    }
    receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
    return receipt
}

func BenchmarkFilters(b *testing.B) {
    dir, err := ioutil.TempDir("", "filtertest")
    if err != nil {
        b.Fatal(err)
    }
    defer os.RemoveAll(dir)

    var (
        db, _      = ethdb.NewLDBDatabase(dir, 0, 0)
        mux        = new(event.TypeMux)
        txFeed     = new(event.Feed)
        rmLogsFeed = new(event.Feed)
        logsFeed   = new(event.Feed)
        chainFeed  = new(event.Feed)
        backend    = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
        key1, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
        addr1      = crypto.PubkeyToAddress(key1.PublicKey)
        addr2      = common.BytesToAddress([]byte("jeff"))
        addr3      = common.BytesToAddress([]byte("ethereum"))
        addr4      = common.BytesToAddress([]byte("random addresses please"))
    )
    defer db.Close()

    genesis := core.GenesisBlockForTesting(db, addr1, big.NewInt(1000000))
    chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 100010, func(i int, gen *core.BlockGen) {
        switch i {
        case 2403:
            receipt := makeReceipt(addr1)
            gen.AddUncheckedReceipt(receipt)
        case 1034:
            receipt := makeReceipt(addr2)
            gen.AddUncheckedReceipt(receipt)
        case 34:
            receipt := makeReceipt(addr3)
            gen.AddUncheckedReceipt(receipt)
        case 99999:
            receipt := makeReceipt(addr4)
            gen.AddUncheckedReceipt(receipt)

        }
    })
    for i, block := range chain {
        core.WriteBlock(db, block)
        if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
            b.Fatalf("failed to insert block number: %v", err)
        }
        if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
            b.Fatalf("failed to insert block number: %v", err)
        }
        if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
            b.Fatal("error writing block receipts:", err)
        }
    }
    b.ResetTimer()

    filter := New(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil)

    for i := 0; i < b.N; i++ {
        logs, _ := filter.Logs(context.Background())
        if len(logs) != 4 {
            b.Fatal("expected 4 logs, got", len(logs))
        }
    }
}

func TestFilters(t *testing.T) {
    dir, err := ioutil.TempDir("", "filtertest")
    if err != nil {
        t.Fatal(err)
    }
    defer os.RemoveAll(dir)

    var (
        db, _      = ethdb.NewLDBDatabase(dir, 0, 0)
        mux        = new(event.TypeMux)
        txFeed     = new(event.Feed)
        rmLogsFeed = new(event.Feed)
        logsFeed   = new(event.Feed)
        chainFeed  = new(event.Feed)
        backend    = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
        key1, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
        addr       = crypto.PubkeyToAddress(key1.PublicKey)

        hash1 = common.BytesToHash([]byte("topic1"))
        hash2 = common.BytesToHash([]byte("topic2"))
        hash3 = common.BytesToHash([]byte("topic3"))
        hash4 = common.BytesToHash([]byte("topic4"))
    )
    defer db.Close()

    genesis := core.GenesisBlockForTesting(db, addr, big.NewInt(1000000))
    chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 1000, func(i int, gen *core.BlockGen) {
        switch i {
        case 1:
            receipt := types.NewReceipt(nil, false, new(big.Int))
            receipt.Logs = []*types.Log{
                {
                    Address: addr,
                    Topics:  []common.Hash{hash1},
                },
            }
            gen.AddUncheckedReceipt(receipt)
        case 2:
            receipt := types.NewReceipt(nil, false, new(big.Int))
            receipt.Logs = []*types.Log{
                {
                    Address: addr,
                    Topics:  []common.Hash{hash2},
                },
            }
            gen.AddUncheckedReceipt(receipt)
        case 998:
            receipt := types.NewReceipt(nil, false, new(big.Int))
            receipt.Logs = []*types.Log{
                {
                    Address: addr,
                    Topics:  []common.Hash{hash3},
                },
            }
            gen.AddUncheckedReceipt(receipt)
        case 999:
            receipt := types.NewReceipt(nil, false, new(big.Int))
            receipt.Logs = []*types.Log{
                {
                    Address: addr,
                    Topics:  []common.Hash{hash4},
                },
            }
            gen.AddUncheckedReceipt(receipt)
        }
    })
    for i, block := range chain {
        core.WriteBlock(db, block)
        if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
            t.Fatalf("failed to insert block number: %v", err)
        }
        if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
            t.Fatalf("failed to insert block number: %v", err)
        }
        if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
            t.Fatal("error writing block receipts:", err)
        }
    }

    filter := New(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})

    logs, _ := filter.Logs(context.Background())
    if len(logs) != 4 {
        t.Error("expected 4 log, got", len(logs))
    }

    filter = New(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}})
    logs, _ = filter.Logs(context.Background())
    if len(logs) != 1 {
        t.Error("expected 1 log, got", len(logs))
    }
    if len(logs) > 0 && logs[0].Topics[0] != hash3 {
        t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
    }

    filter = New(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}})
    logs, _ = filter.Logs(context.Background())
    if len(logs) != 1 {
        t.Error("expected 1 log, got", len(logs))
    }
    if len(logs) > 0 && logs[0].Topics[0] != hash3 {
        t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
    }

    filter = New(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}})

    logs, _ = filter.Logs(context.Background())
    if len(logs) != 2 {
        t.Error("expected 2 log, got", len(logs))
    }

    failHash := common.BytesToHash([]byte("fail"))
    filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}})

    logs, _ = filter.Logs(context.Background())
    if len(logs) != 0 {
        t.Error("expected 0 log, got", len(logs))
    }

    failAddr := common.BytesToAddress([]byte("failmenow"))
    filter = New(backend, 0, -1, []common.Address{failAddr}, nil)

    logs, _ = filter.Logs(context.Background())
    if len(logs) != 0 {
        t.Error("expected 0 log, got", len(logs))
    }

    filter = New(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}})

    logs, _ = filter.Logs(context.Background())
    if len(logs) != 0 {
        t.Error("expected 0 log, got", len(logs))
    }
}