-
Notifications
You must be signed in to change notification settings - Fork 1.9k
core/chains/evm/log: prioritize replay requests #6047
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 all commits
3d1bf92
2719049
2df4ede
71a4344
6c57fe5
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 |
|---|---|---|
|
|
@@ -389,6 +389,14 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error) | |
|
|
||
| b.logger.Debug("Starting the event loop") | ||
| for { | ||
| // Replay requests take priority. | ||
| select { | ||
| case blockNumber := <-b.replayChannel: | ||
| b.onReplayRequest(blockNumber) | ||
| return true, nil | ||
| default: | ||
| } | ||
|
|
||
| select { | ||
| case rawLog := <-chRawLogs: | ||
| b.logger.Debugw("Received a log", | ||
|
|
@@ -402,12 +410,8 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error) | |
| // The eth node connection was terminated so we need to backfill after resubscribing. | ||
| lggr := b.logger | ||
| // Do we have logs in the pool? | ||
| if min := b.logPool.heap.FindMin(); min != nil { | ||
| // They are are invalid, since we may have missed 'removed' logs. | ||
| b.logPool = newLogPool() | ||
| // Note: even if we crash right now, PendingMinBlock is preserved in the database and we will backfill the same. | ||
| blockNum := int64(min.(Uint64)) | ||
| b.backfillBlockNumber.SetValid(blockNum) | ||
| // They are are invalid, since we may have missed 'removed' logs. | ||
| if blockNum := b.invalidatePool(); blockNum > 0 { | ||
| lggr = lggr.With("blockNumber", blockNum) | ||
| } | ||
| lggr.Debugw("Subscription terminated. Backfilling after resubscribing") | ||
|
|
@@ -417,11 +421,7 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error) | |
| needsResubscribe = b.onChangeSubscriberStatus() || needsResubscribe | ||
|
|
||
| case blockNumber := <-b.replayChannel: | ||
| // NOTE: This ignores r.highestNumConfirmations, but it is | ||
| // generally assumed that this will only be performed rarely and | ||
| // manually by someone who knows what he is doing | ||
| b.backfillBlockNumber.SetValid(blockNumber) | ||
| b.logger.Debugw("Returning from the event loop to replay logs from specific block number", "blockNumber", blockNumber) | ||
| b.onReplayRequest(blockNumber) | ||
|
Contributor
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. If we have it above, do we still need it here?
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. Yes, because we only check above, but then sit and wait here. We still need to yield to replay also.
Contributor
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. ah yeah good point |
||
| return true, nil | ||
|
|
||
| case <-debounceResubscribe.C: | ||
|
|
@@ -444,6 +444,27 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error) | |
| } | ||
| } | ||
|
|
||
| // onReplayRequest clears the pool and sets the block backfill number. | ||
| func (b *broadcaster) onReplayRequest(blockNumber int64) { | ||
| _ = b.invalidatePool() | ||
| // NOTE: This ignores r.highestNumConfirmations, but it is | ||
| // generally assumed that this will only be performed rarely and | ||
| // manually by someone who knows what he is doing | ||
| b.backfillBlockNumber.SetValid(blockNumber) | ||
| b.logger.Debugw("Returning from the event loop to replay logs from specific block number", "blockNumber", blockNumber) | ||
| } | ||
|
|
||
| func (b *broadcaster) invalidatePool() int64 { | ||
| if min := b.logPool.heap.FindMin(); min != nil { | ||
| b.logPool = newLogPool() | ||
| // Note: even if we crash right now, PendingMinBlock is preserved in the database and we will backfill the same. | ||
| blockNum := int64(min.(Uint64)) | ||
| b.backfillBlockNumber.SetValid(blockNum) | ||
| return blockNum | ||
| } | ||
| return -1 | ||
| } | ||
|
|
||
| func (b *broadcaster) onNewLog(log types.Log) { | ||
| b.maybeWarnOnLargeBlockNumberDifference(int64(log.BlockNumber)) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if we get something on the replayChannel, but there is already a message waiting on the chRawLogs channel (from before the replay). Would that cause issues once the replay starts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC the replay should only be delayed by one log in the worst case (or one other action here in general, e.g. head), then it would loop again and necessarily select the replay in the priority select.