blob: 4ba66a7e077db3036a30793a68ee5ef2a11754e6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
package filter
// TODO make use of the generic filtering system
import (
"sync"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/state"
)
type FilterManager struct {
eventMux *event.TypeMux
filterMu sync.RWMutex
filterId int
filters map[int]*core.Filter
quit chan struct{}
}
func NewFilterManager(mux *event.TypeMux) *FilterManager {
return &FilterManager{
eventMux: mux,
filters: make(map[int]*core.Filter),
}
}
func (self *FilterManager) Start() {
go self.filterLoop()
}
func (self *FilterManager) Stop() {
close(self.quit)
}
func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) {
self.filterMu.Lock()
defer self.filterMu.Unlock()
id = self.filterId
self.filters[id] = filter
self.filterId++
return id
}
func (self *FilterManager) UninstallFilter(id int) {
self.filterMu.Lock()
defer self.filterMu.Unlock()
delete(self.filters, id)
}
// GetFilter retrieves a filter installed using InstallFilter.
// The filter may not be modified.
func (self *FilterManager) GetFilter(id int) *core.Filter {
self.filterMu.RLock()
defer self.filterMu.RUnlock()
return self.filters[id]
}
func (self *FilterManager) filterLoop() {
// Subscribe to events
events := self.eventMux.Subscribe(
core.PendingBlockEvent{},
//core.ChainEvent{},
state.Logs(nil))
out:
for {
select {
case <-self.quit:
break out
case event := <-events.Chan():
switch event := event.(type) {
case core.ChainEvent:
self.filterMu.RLock()
for _, filter := range self.filters {
if filter.BlockCallback != nil {
filter.BlockCallback(event.Block)
}
}
self.filterMu.RUnlock()
case core.PendingBlockEvent:
self.filterMu.RLock()
for _, filter := range self.filters {
if filter.PendingCallback != nil {
filter.PendingCallback(event.Block)
}
}
self.filterMu.RUnlock()
case state.Logs:
self.filterMu.RLock()
for _, filter := range self.filters {
if filter.LogsCallback != nil {
msgs := filter.FilterLogs(event)
if len(msgs) > 0 {
filter.LogsCallback(msgs)
}
}
}
self.filterMu.RUnlock()
}
}
}
}
|