Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
eth/filters: decouple client notification delivery from event fan-out #2335
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
base: develop
Are you sure you want to change the base?
eth/filters: decouple client notification delivery from event fan-out #2335
Changes from all commits
dd654b2bbe7009File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
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.
TestSlowClientDoesNotStarveOtherSubscribershas two defects that together make it both flaky and unable to detect a regression of the fix it guards.1. No barrier between
EthSubscribereturning and theEventSystemsubscription being installed.FilterAPI.NewPendingTransactionsinstalls the subscription inside a background goroutine after returningrpcSub, and installation only completes whenes.subscriberound-trips through theeventLoop(eth/filters/api.go:251-292,eth/filters/filter_system.go:428-441).EthSubscribereturning therefore establishes no happens-before with installation. Any of the 200txFeed.Sendcalls processed before installation is never fanned out, and because the receive loop demands exactlyeventsdeliveries, one missed event blocks for the full 5s and fails withhealthy subscriber starved by stalled client— a misleading, non-deterministic failure that falsely accuses the code under test. Pre-existing tests in the same package (eth/filters/filter_system_test.go:303,:335,:395,:740) inserttime.Sleepfor exactly this reason, and this test crosses an additional RPC boundary with no barrier at all.2. The timeout window starts after the stall has already resolved, so the test passes pre-fix.
With
queueNotification(queue, tx.Hash())reverted to_ = notifier.Notify(rpcSub.ID, tx.Hash()), the stallednet.Pipesubscriber blocks the sharedeventLoopand thus blockstxFeed.Sendinside the send loop — which carries no time assertion. That block is bounded at ~10s byrpc's write deadline, after which the stalled connection is closed and its subscription removed:Notifier.sendpassescontext.Background(), so the default applies. The remaining events then flow intohealthy, which is created asmake(chan common.Hash, events)and buffers all 200. Only afterwards istimeoutcreated, and the loop drains the buffer instantly. The assertion passes with and without the fix.Impact: no production behavior is affected, but this is the only regression test accompanying a behavior-changing fix. Today it can fail spuriously on loaded CI (burning ~5s); tomorrow a revert or refactor that reintroduces blocking delivery would ship green, and the starvation bug described in the PR body could return undetected.
Suggested fix: add an installation barrier, then assert latency during fan-out rather than after it.
Suggested test: validate the guard by temporarily reverting
queueNotification(queue, tx.Hash())to_ = notifier.Notify(rpcSub.ID, tx.Hash())inFilterAPI.NewPendingTransactionsand confirming the test fails. If it still passes, it does not protect the fix.go test ./eth/filters/ -run TestSlowClientDoesNotStarveOtherSubscribers -race -count=20Uh oh!
There was an error while loading. Please reload this page.