Conversation
A common-state (private chat / basic group) pts gap can strand buffered updates. A live update that arrives behind a gap is buffered in the sequence box's pending. A gap-triggered getDifference replays the same update in OtherUpdates and then calls setState(diff.State). Because the replayed update is routed through the sequence box while the state is still behind, it is buffered again; the following setState advances the box past it, and applyPending drops it as outdated. Dispatch common pts updates from a difference directly instead of routing them through the sequence box. The difference is the authoritative, ordered replay for the gap, and setState records the position it reaches. Channel updates in OtherUpdates keep their existing routing to the channel state. Fixes gotd#1853.
This was referenced Sep 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
A common-state (private chat / basic group) pts gap can strand buffered updates.
A live update that arrives behind a gap is buffered in the sequence box's
pending. A gap-triggeredgetDifferencethen replays the same update inOtherUpdates, andgetDifferencecallssetState(diff.State)afterwards. Because the replayed update is routed through the sequence box while the box state is still behind, it is buffered again; the followingsetStateadvances the box past it, andapplyPendingdrops it asOutdated update, skipping.Reported in #1853 with a concrete reproduction: a bot streaming a long reply via repeated edits, where only a subset of the edits reach the handler (30 wire edits, 17 dispatched in one capture).
This is the common-state counterpart of #1852 (which is the channel
channelDifference.timeoutpath). Possibly the same family as the closed #1623.Fix
Dispatch common pts updates from a difference directly instead of routing them through the sequence box. The difference is the authoritative, ordered replay for the gap, and
setStaterecords the position it reaches. Channel updates inOtherUpdateskeep their existing routing to the channel state.Concretely,
handleUpdates/handleSeq/applyCombinedgain afromDifferenceflag; when set,applyCombinedappends a commonIsPtsUpdateto the batch'sothers(dispatched with the batch) rather than callinghandlePts.Test
telegram/updates/common_getdiff_test.goreproduces the drop deterministically: statePts=10, a live edit atPts=12is buffered behind the gap at 11,getDifferencereplays it inOtherUpdatesand returnsState.Pts=12. Before the fix the edit is dropped; after, it is dispatched.The existing
TestE2Ecovers the channel-routing boundary: channel updates inOtherUpdatesmust still reach the channel state (the first version of this fix dispatched them directly and duplicated them).go test ./telegram/updates/...passes (also with-count=5for the randomized e2e).Fixes #1853.