mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 21:56:43 +00:00
filter 1
This commit is contained in:
parent
5ab65c3a1b
commit
8a2044789a
4 changed files with 38 additions and 24 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue