mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +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",
|
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",
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue