Skip to content

[sui-rpc-api] symbolic resume for the scalar lanes 5/5 - #27755

Closed
wlmyng wants to merge 4 commits into
mainfrom
wlmyng/resolved-range-symbolic-resume
Closed

wlmyng wants to merge 4 commits into
mainfrom
wlmyng/resolved-range-symbolic-resume

Conversation

@wlmyng

@wlmyng wlmyng commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Description

While applying an after cursor, the intra-tx path converts an after-Item cursor into Excluded(coordinate), while the scalar u64 path eagerly computes Included(coordinate + 1). This PR makes both uniformly symbolic, and pushes the +1/u64::MAX handling to ScanBounds<u64>::to_range. This shrinks the ScanCursor trait to coordinate().

In practice, the fetch interval is invariant: to_range projects Excluded(n) and Included(n + 1) to the same Range<u64>. However, the bounds are also read by two frame decisions, which now see the raw coordinate instead of the successor:

  1. ScanBounds::is_empty checks whether a cursor emptied the window and thus should set CursorBound. Included(n + 1) vs Excluded(n + 1) reads as empty, but Excluded(n) vs Excluded(n + 1) does not, so exactly-adjacent bounds no longer set CursorBound eagerly at resolution — the zero-row drain produces the frame instead. This is the current event/intra-tx behavior.
  2. The admission comparison lower_bound_gte used to see Included(n + 1), which ties a window bound at the same coordinate and admits the cursor; Excluded(n) ranks below the tie, so a cursor coinciding with the window's own bound is now rejected outright.

Wire-visible changes outlined below, over window [10, 20):

scenario old → new via
asc, after = Item@19 (window's last item) CursorBound at the request cursor → CheckpointBound at the window end 1
desc, after = Item@9 (one below window) CursorBound at the cursor → the window's natural frame 2
desc, after = Item@14, before = Item@15 frame at before@15 → after@14 (the before's emptying claim no longer fires, so the after's stop-side stamp stands) 1
desc, after = Item@19 unchanged — the stop-side stamp never asks about emptiness
asc, after = Item@14, before = Item@15 unchanged — the asc stop side (before) stamps and claims the same coordinate

Beyond-window cursors still empty at resolution, and u64::MAX handling is unchanged
(the saturation now lives in to_range).

Test plan

  • to_range_collapses_excluded_lo_at_successor
  • raw_after_item_echo_resumes_like_successor_boundary
  • tx_after_item_at_window_edge_defers_to_drain
  • tx_after_item_at_window_edge_descending_keeps_stamped_terminal
  • tx_after_item_below_window_start_descending_is_noop
  • test_list_transactions_after_before_adjacent_empty_results (pre-flip preservation pin)
  • test_list_transactions_after_last_item_ends_at_window_bound (cargo simtest -p sui-e2e-tests list_ledger_history)

Release notes

  • Protocol
  • Nodes (Validators and Full nodes)
  • gRPC
  • JSON-RPC
  • GraphQL
  • CLI
  • Rust SDK

@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 01:54 — with GitHub Actions Inactive
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sui-docs Ready Ready Preview Aug 20, 2026 11:47pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
multisig-toolkit Ignored Ignored Preview Aug 20, 2026 11:47pm
sui-kiosk Ignored Ignored Preview Aug 20, 2026 11:47pm

Request Review

@wlmyng wlmyng changed the title refactor!: symbolic resume for the scalar lanes [sui-rpc-api] symbolic resume for the scalar lanes Aug 19, 2026
@wlmyng wlmyng changed the title [sui-rpc-api] symbolic resume for the scalar lanes [sui-rpc-api] symbolic resume for the scalar lanes 5/5 Aug 19, 2026
@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from 5bc1b3a to 33f153a Compare August 19, 2026 05:19
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:19 — with GitHub Actions Inactive
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:19 — with GitHub Actions Inactive
@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from 33f153a to a04966e Compare August 19, 2026 05:26
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:26 — with GitHub Actions Inactive
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:26 — with GitHub Actions Inactive
@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from a04966e to b009164 Compare August 19, 2026 05:38
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:38 — with GitHub Actions Inactive
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:38 — with GitHub Actions Inactive
@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from b009164 to 5f0d585 Compare August 19, 2026 05:46
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:46 — with GitHub Actions Inactive
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 05:46 — with GitHub Actions Inactive
@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from 5f0d585 to f5288c4 Compare August 19, 2026 06:24
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 06:24 — with GitHub Actions Inactive
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 06:24 — with GitHub Actions Inactive
@wlmyng
wlmyng marked this pull request as ready for review August 19, 2026 06:53
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 19, 2026 06:53 — with GitHub Actions Inactive
@nickvikeras

Copy link
Copy Markdown
Contributor

looks good to me. Thanks again for cleaning this up. Once you have handled the empty-range discrepancy we discussed over slack lmk and I'll take one last look.

@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from f5288c4 to 6f4b4c8 Compare August 20, 2026 23:01
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 20, 2026 23:01 — with GitHub Actions Inactive
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 20, 2026 23:01 — with GitHub Actions Inactive
Base automatically changed from wlmyng/resolved-range-unify to main August 20, 2026 23:44
wlmyng added 4 commits August 20, 2026 16:44
Nothing constructs an Excluded lo in the dense lane yet — resume_lo
canonicalizes Item cursors to their inclusive successor — but the
symbolic-resume flip will. Pin the store-edge collapse first: an Excluded
lo resumes at its successor and saturates at u64::MAX, where the range
empties exactly (MAX is the unoccupiable exclusive sentinel).
…filtered scalar path

(after = item n, before = item n + 1) serves nothing; pin that the frame
is a CursorBound from the ascending stop side (the before cursor), an
expectation the symbolic-resume flip must preserve.
An after-Item cursor admits Excluded(raw) in every lane; the dense lane's
successor arithmetic lives only at the store edge (to_range), where
u64::MAX saturates into an empty fetch. Checkpoints and transactions work
like events. The fetch range is unchanged for every cursor and window —
Item@n and Boundary@n+1 admit identically — so no request serves
different items. The terminal frames of three corner cases change:

- ascending after at the window's last item: the record no longer empties
  at resolution, the zero-row drain ends at the window's own frame —
  CheckpointBound with the window-end cursor instead of a CursorBound
  echo of the request cursor;
- descending after one position below the window start: rejected instead
  of admitted-at-the-tie, so it no longer repins the terminal;
- descending crossed-adjacent cursors: the frame is the descending stop
  side's admission stamp (the after cursor's raw position) instead of the
  collapse path's before-position, honoring the after-Item consumption
  claim.

Descending window-edge and ascending crossed frames are unchanged: their
producers move from the resolution-time collapse to the admission-time
stamp drained through a zero-row scan, pinned by
tx_after_item_at_window_edge_descending_keeps_stamped_terminal and
test_list_transactions_crossed_adjacent_terminal_is_stable. Beyond-window
cursors still empty at resolution; the MAX tests pass unchanged.
Symbolic resume made both lane impls identical and kind-only; the single
caller inlines the two-arm match. The cursor seam is one method:
coordinate().
@wlmyng
wlmyng force-pushed the wlmyng/resolved-range-symbolic-resume branch from 6f4b4c8 to bf4a993 Compare August 20, 2026 23:44
@wlmyng
wlmyng temporarily deployed to sui-typescript-aws-kms-test-env August 20, 2026 23:44 — with GitHub Actions Inactive
nickvikeras added a commit that referenced this pull request Sep 2, 2026
## Description

Unify cursor resumption across scalar and intra-transaction lanes by
making after-Item cursors uniformly symbolic (`Excluded(coordinate)`)
and deferring successor arithmetic to store-edge projection
(`ScanBounds<u64>::to_range`). Also ensures the projected range
emptiness is passed to `ScanTerminal` in fullnode scalar paths so
empty-interval terminal frames do not claim unverified checkpoint
coverage.

Supersedes #27755.

## Test plan

Covered by unit tests in `sui-rpc-api` and `sui-kv-rpc`, plus simtests
in `sui-e2e-tests` (`list_ledger_history`).

## Release notes
- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [x] gRPC: Terminal metadata on queries that end on an empty natural
interval (such as passing an `after` cursor pointing to the last item of
a bounded window) now emits `QueryEndReason::CheckpointBound` with
`watermark.checkpoint = None` instead of `CursorBound`. No client
migration required.
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] Indexing Framework:
@nickvikeras nickvikeras closed this Sep 3, 2026

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – sui-docs bf4a993b Deployed Aug 20, 2026 by vercel[bot]
sui-typescript-aws-kms-test-env bf4a993b Deployed Aug 20, 2026 by wlmyng via Lint, Build, and Test #90225
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.

2 participants