-
Notifications
You must be signed in to change notification settings - Fork 74
test for icebox ordering #2916
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
test for icebox ordering #2916
Conversation
|
This PR is part of a stack of 12 bookmarks:
Created with jj-stack |
|
Claude finished @insipx's task —— View job Code Review CompleteReview Date: December 15, 2025, 19:30 UTC I've reviewed this PR and have identified several issues that haven't been covered by the existing Macroscope comments. Below are my findings: 🔴 Critical Issues1. Potential False Positive in
|
798f6ab to
c7cbc5c
Compare
954055a to
d39a146
Compare
c7cbc5c to
f5c5824
Compare
d39a146 to
69942d5
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2916 +/- ##
==========================================
+ Coverage 73.59% 73.71% +0.11%
==========================================
Files 405 405
Lines 51710 51883 +173
==========================================
+ Hits 38057 38245 +188
+ Misses 13653 13638 -15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
69942d5 to
461cc93
Compare
f5c5824 to
2cfa1e1
Compare
461cc93 to
c3c2c48
Compare
2cfa1e1 to
8fcb993
Compare
8fcb993 to
949d056
Compare
c3c2c48 to
cb3d961
Compare
241233c to
f2e74fa
Compare
3b21dc8 to
9a5370b
Compare
f2e74fa to
13e19c2
Compare
9a5370b to
debc116
Compare
13e19c2 to
7eec7fa
Compare
7eec7fa to
93c4fb2
Compare
debc116 to
5ab6d8e
Compare
5ab6d8e to
7840c4a
Compare
00361b4 to
ecdd510
Compare
7840c4a to
38c66a7
Compare
7d5e9ae to
d9096ee
Compare
d9096ee to
92a59ae
Compare
<!-- Macroscope's pull request summary starts here --> <!-- Macroscope will only edit the content between these invisible markers, and the markers themselves will not be visible in the GitHub rendered markdown. --> <!-- If you delete either of the start / end markers from your PR's description, Macroscope will post its summary as a comment. --> ### Refactor icebox ordering by deduplicating `OrphanedEnvelope` in `protocol.InMemoryCursorStore` and adjusting ordering tests for icebox behavior Replace the icebox `Vec` with a `HashSet` in `InMemoryCursorStore`, adjust recursive child resolution, and update ordering and tests to remove per-iteration timestamp sorting and to assert dependency resolution. Add custom equality for `OrphanedEnvelope` that ignores payload and introduce small test utilities for formatting and cursor iteration. #### 📍Where to Start Start with `Ordered<T,R,S>::order` in [file:xmtp_api_d14n/src/protocol/order.rs], then review `InMemoryCursorStore` and `resolve_children_inner` in [file:xmtp_api_d14n/src/protocol/in_memory_cursor_store.rs]. ---- <!-- Macroscope's review summary starts here --> <details> <summary>📊 <a href="https://app.macroscope.com">Macroscope</a> summarized 74be9b4. 17 files reviewed, 14 issues evaluated, 12 issues filtered, 0 comments posted</summary> ### 🗂️ Filtered Issues <details> <summary>xmtp_api_d14n/src/protocol/in_memory_cursor_store.rs — 0 comments posted, 3 evaluated, 3 filtered</summary> - [line 12](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/in_memory_cursor_store.rs#L12): Changing `icebox` from `Vec<OrphanedEnvelope>` to `HashSet<OrphanedEnvelope>` can cause data loss. The `Hash` and `PartialEq` implementations for `OrphanedEnvelope` intentionally ignore the `payload` field. If two orphaned envelopes have identical `cursor`, `depends_on`, and `group_id` but different `payload` values, only one will be stored in the `HashSet`, silently losing the other envelope's payload data. <b>[ Low confidence ]</b> - [line 129](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/in_memory_cursor_store.rs#L129): The `resolve_children` method no longer removes resolved orphans from the icebox. The old implementation used `extract_if` to remove matching orphans, but the new implementation only filters and clones without modifying the icebox. This causes orphaned envelopes to accumulate indefinitely, leading to memory growth and returning the same already-resolved orphans on subsequent calls. <b>[ Already posted ]</b> - [line 155](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/in_memory_cursor_store.rs#L155): The recursive `resolve_children_inner` function includes all children whose `depends_on` is not empty (line 155), but orphaned envelopes by definition always have non-empty `depends_on`. The condition `if !c.depends_on.is_empty()` at line 155 should likely check something more specific, such as whether the child's dependencies were actually satisfied by the input cursors, to avoid unnecessary recursive calls. <b>[ Low confidence ]</b> </details> <details> <summary>xmtp_api_d14n/src/protocol/order.rs — 0 comments posted, 10 evaluated, 9 filtered</summary> - [line 83](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L83): In `recover_lost_children`, the variable `cursors` is shadowed - first declared as `Vec<Cursor>` on line 68, then redeclared as `HashSet<Cursor>` on line 83. While not a runtime bug, this could lead to confusion if the `Vec` version is accidentally used after the shadowing (currently it's not, but future modifications could introduce errors). <b>[ Low confidence ]</b> - [line 134](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L134): The new `order` implementation changes the ordering from prepending (`splice(0..0, ...)`) to appending (`append`). The old code placed resolved envelopes at the front followed by missing envelopes, then re-ran timestamp sort. The new code appends them at the end without re-running timestamp sort inside the loop. This ordering change could affect causal sort correctness if the sort algorithm depends on resolved dependencies appearing before dependent envelopes in the input list. <b>[ Low confidence ]</b> - [line 209](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L209): In `assert_topic_cursor_seen`, the chained `.unwrap()` calls on line 209 (`cursor.get(&env.topic().unwrap()).unwrap()`) will panic with an unclear message if either `env.topic()` returns `None` or if the topic is not present in the cursor. This could produce confusing test failures since the panic message won't indicate which unwrap failed. Consider using `expect()` with descriptive messages or propagating the error via `prop_assert!`. <b>[ Already posted ]</b> - [line 219](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L219): In `assert_dependencies_satisfied`, the call `env.topic().unwrap()` on line 219 will panic if `env.topic()` returns `None`. While similar code exists in `assert_topic_cursor_seen`, this function uses `get_or_default` for the cursor lookup (which handles missing topics gracefully), creating an inconsistency where topic existence is handled differently than in the sibling helper function. <b>[ Already posted ]</b> - [line 283](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L283): Potential deadlock risk in `make_available`: locks are acquired in order `unavailable` then `available`. If any other code path acquires these locks in the opposite order (`available` then `unavailable`), a deadlock could occur. <b>[ Low confidence ]</b> - [line 285](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L285): In `make_available`, calling `v.remove(idx)` will panic if `idx >= v.len()`. There is no bounds check before attempting to remove the element at the given index from `unavailable`. <b>[ Low confidence ]</b> - [line 295](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L295): In `all_envelopes()`, the `unavailable()` envelopes are excluded from the result. This causes `find_envelope()` to return `None` for any envelope that is in the unavailable list. In `has_unavailable_in_dependency_chain()`, if a transitive dependency itself is in the unavailable list, `find_envelope(&cursor)` won't find it, so its own dependencies won't be checked, potentially missing transitive unavailable dependencies in the chain. <b>[ Already posted ]</b> - [line 392](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L392): In `orders_with_unresolvable_dependencies`, `assert_dependencies_satisfied(envelope, &mut topic_cursor)` at line 392 takes a mutable reference to `topic_cursor` inside a loop. If this function modifies `topic_cursor`, each subsequent iteration operates on modified state, which could cause inconsistent verification behavior or false positives/negatives in the test. <b>[ Low confidence ]</b> - [line 485](https://github.com/xmtp/libxmtp/blob/74be9b416be85024e9af0acee30e53d59a90239b/xmtp_api_d14n/src/protocol/order.rs#L485): In `orders_with_recovered_children`, `store.resolve_children(&[newly_available.cursor()])` at line 485 is called AFTER `ordered.order()` completes at line 476-478. If `order()` already processed and removed children from the store's orphan/icebox during ordering, this call may return an empty result even when children were actually recovered. This would cause `had_children` to be `false`, skipping the assertions at lines 501-527 and potentially masking bugs in the ordering logic where children aren't properly recovered. <b>[ Already posted ]</b> </details> </details><!-- Macroscope's review summary ends here --> <!-- Macroscope's pull request summary ends here -->
Deduplicate and recursively resolve orphaned envelopes in
xmtp_api_d14n::protocol::InMemoryCursorStoreto test icebox orderingConvert the icebox to a
HashSetwith customEq/HashonOrphanedEnvelopethat ignore payload bytes, add recursive child resolution without removal, and adjust ordering to sort by timestamp once before the loop. Tests add regression cases, new formatting helpers, and builder utilities for orphans and cursors.📍Where to Start
Start with the ordering flow in
Ordered<T,R,S>::orderin xmtp_api_d14n/src/protocol/order.rs, then review icebox behavior inInMemoryCursorStoreandresolve_children_innerin xmtp_api_d14n/src/protocol/in_memory_cursor_store.rs, and theOrphanedEnvelopeequality/hash changes in xmtp_proto/src/types/orphaned_envelope.rs.Macroscope summarized 92a59ae.