diff --git a/eth/backend.go b/eth/backend.go index b5318f9679..b13d408351 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -342,7 +342,7 @@ func (s *FullNodeService) APIs() []rpc.API { }, { Namespace: "eth", Version: "1.0", - Service: filters.NewPublicFilterAPI(s.chainDb, s.eventMux), + Service: filters.NewPublicFilterAPI(s.ApiBackend), Public: true, }, { Namespace: "admin", diff --git a/eth/filters/api.go b/eth/filters/api.go index 393019f8b0..869cafd937 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" "golang.org/x/net/context" @@ -50,10 +51,11 @@ const ( // PublicFilterAPI offers support to create and manage filters. This will allow external clients to retrieve various // information related to the Ethereum protocol such als blocks, transactions and logs. type PublicFilterAPI struct { - mux *event.TypeMux + apiBackend ethapi.Backend quit chan struct{} chainDb ethdb.Database + mux *event.TypeMux filterManager *FilterSystem @@ -73,10 +75,11 @@ type PublicFilterAPI struct { } // NewPublicFilterAPI returns a new PublicFilterAPI instance. -func NewPublicFilterAPI(chainDb ethdb.Database, mux *event.TypeMux) *PublicFilterAPI { +func NewPublicFilterAPI(apiBackend ethapi.Backend) *PublicFilterAPI { svc := &PublicFilterAPI{ - mux: mux, - chainDb: chainDb, + apiBackend: apiBackend, + mux: apiBackend.EventMux(), + chainDb: apiBackend.ChainDb(), filterManager: NewFilterSystem(mux), filterMapping: make(map[string]int), logQueue: make(map[int]*logQueue), @@ -141,7 +144,7 @@ func (s *PublicFilterAPI) NewBlockFilter() (string, error) { } s.blockMu.Lock() - filter := New(s.chainDb) + filter := New(s.apiBackend) id, err := s.filterManager.Add(filter, ChainFilter) if err != nil { return "", err @@ -177,7 +180,7 @@ func (s *PublicFilterAPI) NewPendingTransactionFilter() (string, error) { s.transactionMu.Lock() defer s.transactionMu.Unlock() - filter := New(s.chainDb) + filter := New(s.apiBackend) id, err := s.filterManager.Add(filter, PendingTxFilter) if err != nil { return "", err @@ -206,7 +209,7 @@ func (s *PublicFilterAPI) newLogFilter(earliest, latest int64, addresses []commo s.logMu.Lock() defer s.logMu.Unlock() - filter := New(s.chainDb) + filter := New(s.apiBackend) id, err := s.filterManager.Add(filter, LogFilter) if err != nil { return 0, err @@ -432,7 +435,7 @@ func (s *PublicFilterAPI) NewFilter(args NewFilterArgs) (string, error) { // GetLogs returns the logs matching the given argument. func (s *PublicFilterAPI) GetLogs(args NewFilterArgs) []vmlog { - filter := New(s.chainDb) + filter := New(s.apiBackend) filter.SetBeginBlock(args.FromBlock.Int64()) filter.SetEndBlock(args.ToBlock.Int64()) filter.SetAddresses(args.Addresses) diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 995b588fb2..f57d375c66 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -25,6 +25,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/rpc" ) type AccountChange struct { @@ -33,6 +35,8 @@ type AccountChange struct { // Filtering interface type Filter struct { + apiBackend ethapi.Backend + created time.Time db ethdb.Database @@ -47,8 +51,11 @@ type Filter struct { // Create a new filter which uses a bloom filter on blocks to figure out whether a particular block // is interesting or not. -func New(db ethdb.Database) *Filter { - return &Filter{db: db} +func New(apiBackend ethapi.Backend) *Filter { + return &Filter{ + apiBackend: apiBackend, + db: apiBackend.ChainDb(), + } } // Set the earliest and latest block for filtering. @@ -72,15 +79,15 @@ func (self *Filter) SetTopics(topics [][]common.Hash) { // Run filters logs with the current parameters set func (self *Filter) Find() vm.Logs { - latestHash := core.GetHeadBlockHash(self.db) - latestBlock := core.GetBlock(self.db, latestHash, core.GetBlockNumber(self.db, latestHash)) + headBlockNumber := self.apiBackend.HeaderByNumber(rpc.LatestBlockNumber).Number.Uint64() + var beginBlockNo uint64 = uint64(self.begin) if self.begin == -1 { - beginBlockNo = latestBlock.NumberU64() + beginBlockNo = headBlockNumber } var endBlockNo uint64 = uint64(self.end) if self.end == -1 { - endBlockNo = latestBlock.NumberU64() + endBlockNo = headBlockNumber } // if no addresses are present we can't make use of fast search which @@ -126,19 +133,17 @@ func (self *Filter) getLogs(start, end uint64) (logs vm.Logs) { var block *types.Block for i := start; i <= end; i++ { - hash := core.GetCanonicalHash(self.db, i) - if hash != (common.Hash{}) { - block = core.GetBlock(self.db, hash, i) - } else { // block not found + header := self.apiBackend.HeaderByNumber(rpc.BlockNumber(i)) + if header == nil { return logs } // Use bloom filtering to see if this block is interesting given the // current parameters - if self.bloomFilter(block) { + if self.bloomFilter(header.Bloom) { // Get the logs of the block var ( - receipts = core.GetBlockReceipts(self.db, block.Hash(), i) + receipts = self.apiBackend.GetReceipts(ctx, header.Hash()) unfiltered vm.Logs ) for _, receipt := range receipts { @@ -202,11 +207,11 @@ Logs: return ret } -func (self *Filter) bloomFilter(block *types.Block) bool { +func (self *Filter) bloomFilter(bloom types.Bloom) bool { if len(self.addresses) > 0 { var included bool for _, addr := range self.addresses { - if types.BloomLookup(block.Bloom(), addr) { + if types.BloomLookup(bloom, addr) { included = true break } @@ -220,7 +225,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool { for _, sub := range self.topics { var included bool for _, topic := range sub { - if (topic == common.Hash{}) || types.BloomLookup(block.Bloom(), topic) { + if (topic == common.Hash{}) || types.BloomLookup(bloom, topic) { included = true break } diff --git a/les/backend.go b/les/backend.go index d261a92ecd..0b9276ec2e 100644 --- a/les/backend.go +++ b/les/backend.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/ethdb" @@ -137,6 +138,11 @@ func (s *LightNodeService) APIs() []rpc.API { Version: "1.0", Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: filters.NewPublicFilterAPI(s.ApiBackend), + Public: true, }, { Namespace: "net", Version: "1.0",