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", Namespace: "eth",
Version: "1.0", Version: "1.0",
Service: filters.NewPublicFilterAPI(s.chainDb, s.eventMux), Service: filters.NewPublicFilterAPI(s.ApiBackend),
Public: true, Public: true,
}, { }, {
Namespace: "admin", Namespace: "admin",

View file

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"golang.org/x/net/context" "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 // 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. // information related to the Ethereum protocol such als blocks, transactions and logs.
type PublicFilterAPI struct { type PublicFilterAPI struct {
mux *event.TypeMux apiBackend ethapi.Backend
quit chan struct{} quit chan struct{}
chainDb ethdb.Database chainDb ethdb.Database
mux *event.TypeMux
filterManager *FilterSystem filterManager *FilterSystem
@ -73,10 +75,11 @@ type PublicFilterAPI struct {
} }
// NewPublicFilterAPI returns a new PublicFilterAPI instance. // NewPublicFilterAPI returns a new PublicFilterAPI instance.
func NewPublicFilterAPI(chainDb ethdb.Database, mux *event.TypeMux) *PublicFilterAPI { func NewPublicFilterAPI(apiBackend ethapi.Backend) *PublicFilterAPI {
svc := &PublicFilterAPI{ svc := &PublicFilterAPI{
mux: mux, apiBackend: apiBackend,
chainDb: chainDb, mux: apiBackend.EventMux(),
chainDb: apiBackend.ChainDb(),
filterManager: NewFilterSystem(mux), filterManager: NewFilterSystem(mux),
filterMapping: make(map[string]int), filterMapping: make(map[string]int),
logQueue: make(map[int]*logQueue), logQueue: make(map[int]*logQueue),
@ -141,7 +144,7 @@ func (s *PublicFilterAPI) NewBlockFilter() (string, error) {
} }
s.blockMu.Lock() s.blockMu.Lock()
filter := New(s.chainDb) filter := New(s.apiBackend)
id, err := s.filterManager.Add(filter, ChainFilter) id, err := s.filterManager.Add(filter, ChainFilter)
if err != nil { if err != nil {
return "", err return "", err
@ -177,7 +180,7 @@ func (s *PublicFilterAPI) NewPendingTransactionFilter() (string, error) {
s.transactionMu.Lock() s.transactionMu.Lock()
defer s.transactionMu.Unlock() defer s.transactionMu.Unlock()
filter := New(s.chainDb) filter := New(s.apiBackend)
id, err := s.filterManager.Add(filter, PendingTxFilter) id, err := s.filterManager.Add(filter, PendingTxFilter)
if err != nil { if err != nil {
return "", err return "", err
@ -206,7 +209,7 @@ func (s *PublicFilterAPI) newLogFilter(earliest, latest int64, addresses []commo
s.logMu.Lock() s.logMu.Lock()
defer s.logMu.Unlock() defer s.logMu.Unlock()
filter := New(s.chainDb) filter := New(s.apiBackend)
id, err := s.filterManager.Add(filter, LogFilter) id, err := s.filterManager.Add(filter, LogFilter)
if err != nil { if err != nil {
return 0, err return 0, err
@ -432,7 +435,7 @@ func (s *PublicFilterAPI) NewFilter(args NewFilterArgs) (string, error) {
// GetLogs returns the logs matching the given argument. // GetLogs returns the logs matching the given argument.
func (s *PublicFilterAPI) GetLogs(args NewFilterArgs) []vmlog { func (s *PublicFilterAPI) GetLogs(args NewFilterArgs) []vmlog {
filter := New(s.chainDb) filter := New(s.apiBackend)
filter.SetBeginBlock(args.FromBlock.Int64()) filter.SetBeginBlock(args.FromBlock.Int64())
filter.SetEndBlock(args.ToBlock.Int64()) filter.SetEndBlock(args.ToBlock.Int64())
filter.SetAddresses(args.Addresses) filter.SetAddresses(args.Addresses)

View file

@ -25,6 +25,8 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/rpc"
) )
type AccountChange struct { type AccountChange struct {
@ -33,6 +35,8 @@ type AccountChange struct {
// Filtering interface // Filtering interface
type Filter struct { type Filter struct {
apiBackend ethapi.Backend
created time.Time created time.Time
db ethdb.Database 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 // Create a new filter which uses a bloom filter on blocks to figure out whether a particular block
// is interesting or not. // is interesting or not.
func New(db ethdb.Database) *Filter { func New(apiBackend ethapi.Backend) *Filter {
return &Filter{db: db} return &Filter{
apiBackend: apiBackend,
db: apiBackend.ChainDb(),
}
} }
// Set the earliest and latest block for filtering. // 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 // Run filters logs with the current parameters set
func (self *Filter) Find() vm.Logs { func (self *Filter) Find() vm.Logs {
latestHash := core.GetHeadBlockHash(self.db) headBlockNumber := self.apiBackend.HeaderByNumber(rpc.LatestBlockNumber).Number.Uint64()
latestBlock := core.GetBlock(self.db, latestHash, core.GetBlockNumber(self.db, latestHash))
var beginBlockNo uint64 = uint64(self.begin) var beginBlockNo uint64 = uint64(self.begin)
if self.begin == -1 { if self.begin == -1 {
beginBlockNo = latestBlock.NumberU64() beginBlockNo = headBlockNumber
} }
var endBlockNo uint64 = uint64(self.end) var endBlockNo uint64 = uint64(self.end)
if self.end == -1 { if self.end == -1 {
endBlockNo = latestBlock.NumberU64() endBlockNo = headBlockNumber
} }
// if no addresses are present we can't make use of fast search which // 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 var block *types.Block
for i := start; i <= end; i++ { for i := start; i <= end; i++ {
hash := core.GetCanonicalHash(self.db, i) header := self.apiBackend.HeaderByNumber(rpc.BlockNumber(i))
if hash != (common.Hash{}) { if header == nil {
block = core.GetBlock(self.db, hash, i)
} else { // block not found
return logs return logs
} }
// Use bloom filtering to see if this block is interesting given the // Use bloom filtering to see if this block is interesting given the
// current parameters // current parameters
if self.bloomFilter(block) { if self.bloomFilter(header.Bloom) {
// Get the logs of the block // Get the logs of the block
var ( var (
receipts = core.GetBlockReceipts(self.db, block.Hash(), i) receipts = self.apiBackend.GetReceipts(ctx, header.Hash())
unfiltered vm.Logs unfiltered vm.Logs
) )
for _, receipt := range receipts { for _, receipt := range receipts {
@ -202,11 +207,11 @@ Logs:
return ret return ret
} }
func (self *Filter) bloomFilter(block *types.Block) bool { func (self *Filter) bloomFilter(bloom types.Bloom) bool {
if len(self.addresses) > 0 { if len(self.addresses) > 0 {
var included bool var included bool
for _, addr := range self.addresses { for _, addr := range self.addresses {
if types.BloomLookup(block.Bloom(), addr) { if types.BloomLookup(bloom, addr) {
included = true included = true
break break
} }
@ -220,7 +225,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
for _, sub := range self.topics { for _, sub := range self.topics {
var included bool var included bool
for _, topic := range sub { for _, topic := range sub {
if (topic == common.Hash{}) || types.BloomLookup(block.Bloom(), topic) { if (topic == common.Hash{}) || types.BloomLookup(bloom, topic) {
included = true included = true
break break
} }

View file

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/downloader" "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/eth/gasprice"
"github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -137,6 +138,11 @@ func (s *LightNodeService) APIs() []rpc.API {
Version: "1.0", Version: "1.0",
Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux),
Public: true, Public: true,
}, {
Namespace: "eth",
Version: "1.0",
Service: filters.NewPublicFilterAPI(s.ApiBackend),
Public: true,
}, { }, {
Namespace: "net", Namespace: "net",
Version: "1.0", Version: "1.0",