This commit is contained in:
zsfelfoldi 2016-06-21 16:39:40 +02:00
parent 5ab65c3a1b
commit 8a2044789a
4 changed files with 38 additions and 24 deletions

View file

@ -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",

View file

@ -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)

View file

@ -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
}

View file

@ -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",