Skip to content

Fix #208: skip stale-snapshot resume on SessionVerId bump#209

Merged
pedrosakuma merged 2 commits into
mainfrom
fix/208-stale-snapshot-sessionverid
Jul 6, 2026
Merged

Fix #208: skip stale-snapshot resume on SessionVerId bump#209
pedrosakuma merged 2 commits into
mainfrom
fix/208-stale-snapshot-sessionverid

Conversation

@pedrosakuma

Copy link
Copy Markdown
Owner

Fixes #208.

HydrateFromSnapshotAsync only compared snapshot.SessionId against the current session, never SessionVerId. After a cold-start EstablishReuse reject forces a fresh Negotiate (bumping SessionVerId), the outbound app seq counter and inbound/outstanding-order state were still resumed from the pre-bump snapshot, silently desyncing MsgSeqNum from what the venue expects for the new session.

Fix

HydrateFromSnapshotAsync now also checks snapshot.SessionVerId against the (possibly bumped) options.SessionVerId and skips resuming state when they differ, logging via new StaleSnapshotSessionVerIdIgnored.

Tests

  • New regression test ColdResume_EstablishRejectedUnnegotiated_DoesNotResumeOutboundSeqFromStaleSnapshot verifying outbound seq starts at 1 (not the stale snapshot's value) after a rejected cold-start reattach.
  • Added PeekNextOutboundSeqNumForTesting internal test hook.
  • Full unit suite (211 tests) passes; dotnet format --verify-no-changes clean.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Copilot and others added 2 commits July 6, 2026 18:47
HydrateFromSnapshotAsync only compared snapshot.SessionId against the
current session, never SessionVerId. After a cold-start EstablishReuse
reject forces a fresh Negotiate (bumping SessionVerId), the outbound
app seq counter and inbound/outstanding-order state were still resumed
from the pre-bump snapshot, silently desyncing MsgSeqNum from what the
venue expects for the new session.

Now HydrateFromSnapshotAsync also checks snapshot.SessionVerId against
the (possibly bumped) options.SessionVerId and skips resuming state
when they differ, logging via new StaleSnapshotSessionVerIdIgnored.

Adds a regression test verifying the outbound seq starts at 1 (not the
stale snapshot's LastOutboundSeqNum + 1) after a rejected cold-start
reattach, via new PeekNextOutboundSeqNumForTesting test hook.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The prior fix compared snapshot.SessionVerId against the current
options.SessionVerId unconditionally, which also broke the legitimate
warm-reconnect path (explicit ReconnectAsync/AlwaysNegotiate) where the
in-process outbound counter is deliberately carried across a bumped
SessionVerId (Spec_4_7_Retransmit/ReconnectRetransmitTests conformance
regression).

Narrow the fix to only suppress snapshot resume for the specific #208
scenario: TryColdResumeAsync's recoverable-EstablishReuse-reject
fallback, via a one-shot _suppressNextSnapshotResume flag consumed by
the very next HydrateFromSnapshotAsync call. This leaves the
intentional live-reconnect sequence continuity behavior untouched.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pedrosakuma pedrosakuma merged commit aec0a51 into main Jul 6, 2026
6 of 7 checks passed
@pedrosakuma pedrosakuma deleted the fix/208-stale-snapshot-sessionverid branch July 6, 2026 18:57
pedrosakuma pushed a commit to pedrosakuma/B3TradingPlatform that referenced this pull request Jul 6, 2026
Picks up the fix from pedrosakuma/B3EntryPointClient#209 for #208:
HydrateFromSnapshotAsync previously resumed the outbound sequence
counter from a stale snapshot even when SessionVerId had bumped on a
fresh Negotiate, causing silent NotApplied gaps on the venue side
after a trading-host reconnect (root cause of a live incident where
accepted orders never reached the book).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
pedrosakuma added a commit to pedrosakuma/B3TradingPlatform that referenced this pull request Jul 6, 2026
* fix: bump B3.EntryPoint.Client to 0.16.1

Picks up the fix from pedrosakuma/B3EntryPointClient#209 for #208:
HydrateFromSnapshotAsync previously resumed the outbound sequence
counter from a stale snapshot even when SessionVerId had bumped on a
fresh Negotiate, causing silent NotApplied gaps on the venue side
after a trading-host reconnect (root cause of a live incident where
accepted orders never reached the book).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: align Microsoft.Extensions.* to 10.0.9 for B3.EntryPoint.Client 0.16.1

0.16.1 raised its own transitive floor on Microsoft.Extensions.Logging.Abstractions
and Microsoft.Extensions.Options to >=10.0.9, which conflicted (NU1605 downgrade
error) with the repo-wide 10.0.8 pin used by bench/B3.Trading.LoadTest and
bench/B3.Trading.Benchmarks. Bumping the whole Microsoft.Extensions.* family
together to 10.0.9 keeps all packages in that family on a consistent version.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HydrateFromSnapshotAsync resumes outbound seq from stale snapshot after cold-start Negotiate fallback (SessionVerId bump ignored)

1 participant