-
Notifications
You must be signed in to change notification settings - Fork 171
eth/filters,ethclient,node: install newSideHeads subscription #293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
6ae8387
bf5bd12
c8cf61d
85e4d0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,8 @@ const ( | |
| PendingTransactionsSubscription | ||
| // BlocksSubscription queries hashes for blocks that are imported | ||
| BlocksSubscription | ||
| // SideBlocksSubscription queries blocks that are imported non-canonically | ||
| SideBlocksSubscription | ||
| // LastSubscription keeps track of the last index | ||
| LastIndexSubscription | ||
| ) | ||
|
|
@@ -93,6 +95,7 @@ type EventSystem struct { | |
| rmLogsSub event.Subscription // Subscription for removed log event | ||
| pendingLogsSub event.Subscription // Subscription for pending log event | ||
| chainSub event.Subscription // Subscription for new chain event | ||
| chainSideSub event.Subscription // Subscription for new side chain event | ||
|
|
||
| // Channels | ||
| install chan *subscription // install filter for event notification | ||
|
|
@@ -102,6 +105,7 @@ type EventSystem struct { | |
| pendingLogsCh chan []*types.Log // Channel to receive new log event | ||
| rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event | ||
| chainCh chan core.ChainEvent // Channel to receive new chain event | ||
| chainSideCh chan core.ChainSideEvent // Channel to receive new side chain event | ||
| } | ||
|
|
||
| // NewEventSystem creates a new manager that listens for event on the given mux, | ||
|
|
@@ -121,17 +125,19 @@ func NewEventSystem(backend Backend, lightMode bool) *EventSystem { | |
| rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), | ||
| pendingLogsCh: make(chan []*types.Log, logsChanSize), | ||
| chainCh: make(chan core.ChainEvent, chainEvChanSize), | ||
| chainSideCh: make(chan core.ChainSideEvent, chainEvChanSize), | ||
| } | ||
|
|
||
| // Subscribe events | ||
| m.txsSub = m.backend.SubscribeNewTxsEvent(m.txsCh) | ||
| m.logsSub = m.backend.SubscribeLogsEvent(m.logsCh) | ||
| m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh) | ||
| m.chainSub = m.backend.SubscribeChainEvent(m.chainCh) | ||
| m.chainSideSub = m.backend.SubscribeChainSideEvent(m.chainSideCh) | ||
| m.pendingLogsSub = m.backend.SubscribePendingLogsEvent(m.pendingLogsCh) | ||
|
|
||
| // Make sure none of the subscriptions are empty | ||
| if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || m.pendingLogsSub == nil { | ||
| if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || m.chainSideSub == nil || m.pendingLogsSub == nil { | ||
| log.Crit("Subscribe for event system failed") | ||
| } | ||
|
|
||
|
|
@@ -290,6 +296,22 @@ func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscripti | |
| return es.subscribe(sub) | ||
| } | ||
|
|
||
| // SubscribeNewSideHeads creates a subscription that writes the header of a block that is | ||
| // imported as a side chain. | ||
| func (es *EventSystem) SubscribeNewSideHeads(headers chan *types.Header) *Subscription { | ||
| sub := &subscription{ | ||
| id: rpc.NewID(), | ||
| typ: SideBlocksSubscription, | ||
| created: time.Now(), | ||
| logs: make(chan []*types.Log), | ||
| hashes: make(chan []common.Hash), | ||
| headers: headers, | ||
| installed: make(chan struct{}), | ||
| err: make(chan error), | ||
| } | ||
| return es.subscribe(sub) | ||
| } | ||
|
|
||
| // SubscribePendingTxs creates a subscription that writes transaction hashes for | ||
| // transactions that enter the transaction pool. | ||
| func (es *EventSystem) SubscribePendingTxs(hashes chan []common.Hash) *Subscription { | ||
|
|
@@ -366,6 +388,25 @@ func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) | |
| } | ||
| } | ||
|
|
||
| func (es *EventSystem) handleChainSideEvent(filters filterIndex, ev core.ChainSideEvent) { | ||
| for _, f := range filters[SideBlocksSubscription] { | ||
| f.headers <- ev.Block.Header() | ||
| } | ||
| // Handle filtered log eventing similarly to the newHead event, except that 'remove' will always be set to true | ||
| // (indicating the logs come from a non-canonical block). | ||
| // When newHeads and newSideHeads are subscribed to at the same time, this can result in certain logs being broadcast | ||
| // repetitiously. | ||
| if es.lightMode && len(filters[LogsSubscription]) > 0 { | ||
| es.lightFilterNewSideHead(ev.Block.Header(), func(header *types.Header, remove bool) { | ||
| for _, f := range filters[LogsSubscription] { | ||
| if matchedLogs := es.lightFilterLogs(header, f.logsCrit.Addresses, f.logsCrit.Topics, remove); len(matchedLogs) > 0 { | ||
| f.logs <- matchedLogs | ||
| } | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func(*types.Header, bool)) { | ||
| oldh := es.lastHead | ||
| es.lastHead = newHeader | ||
|
|
@@ -399,6 +440,10 @@ func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func | |
| } | ||
| } | ||
|
|
||
| func (es *EventSystem) lightFilterNewSideHead(header *types.Header, callBack func(*types.Header, bool)) { | ||
| callBack(header, true) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is noteworthy; logs from side chain blocks will always be marked |
||
| } | ||
|
|
||
| // filter logs of a single header in light client mode | ||
| func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []*types.Log { | ||
| if bloomFilter(header.Bloom, addresses, topics) { | ||
|
|
@@ -448,6 +493,7 @@ func (es *EventSystem) eventLoop() { | |
| es.rmLogsSub.Unsubscribe() | ||
| es.pendingLogsSub.Unsubscribe() | ||
| es.chainSub.Unsubscribe() | ||
| es.chainSideSub.Unsubscribe() | ||
| }() | ||
|
|
||
| index := make(filterIndex) | ||
|
|
@@ -467,6 +513,8 @@ func (es *EventSystem) eventLoop() { | |
| es.handlePendingLogs(index, ev) | ||
| case ev := <-es.chainCh: | ||
| es.handleChainEvent(index, ev) | ||
| case ev := <-es.chainSideCh: | ||
| es.handleChainSideEvent(index, ev) | ||
|
|
||
| case f := <-es.install: | ||
| if f.typ == MinedAndPendingLogsSubscription { | ||
|
|
@@ -497,6 +545,8 @@ func (es *EventSystem) eventLoop() { | |
| return | ||
| case <-es.chainSub.Err(): | ||
| return | ||
| case <-es.chainSideSub.Err(): | ||
| return | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.