Skip to content

feat: [DSM-148] CertifiedSlicePool::classify_advert() - #11601

Merged
alin-at-dfinity merged 3 commits into
masterfrom
alin/DSM-148-classify-advert
Sep 17, 2026
Merged

alin-at-dfinity merged 3 commits into
masterfrom
alin/DSM-148-classify-advert

Conversation

@alin-at-dfinity

Copy link
Copy Markdown
Contributor

Classifies an advertised stream header by how much of its content the pool already has: accounted for by the cached stream position (InPayload), covered by the pooled slice (Pooled), covered by the peer's recorded header (Duplicate), or none of the above (Actionable). Content is messages or signals; or a begin far enough along to garbage collect a reject signal of ours, which is worth fetching on its own, hence the have_reject_signal_between argument.

Also restores peer_header() as a plain accessor, for the advert handler and (later) the advert task to read the recorded headers back.

Nothing calls this yet; the handler follows.

@alin-at-dfinity
alin-at-dfinity requested a review from a team as a code owner September 17, 2026 08:47
@github-actions github-actions Bot added the feat label Sep 17, 2026
@zeropath-ai

zeropath-ai Bot commented Sep 17, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 3511248.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► rs/interfaces/src/messaging.rs
    Add XNetAdvertOutcome enum and as_str method
► rs/xnet/payload_builder/src/certified_slice_pool.rs
    Use Arc for header references; broaden imports; implement classify_advert and record_peer_header; add decode_slice_header helper
► rs/xnet/payload_builder/tests/certified_slice_pool.rs
    Update tests to use XNetAdvertOutcome; adjust imports; expand test coverage for classify_advert scenarios

@alin-at-dfinity
alin-at-dfinity added this pull request to stack #11604 September 17, 2026 09:16
An error occurred while trying to automatically change base from alin/DSM-148-fake-certified-state to master September 17, 2026 09:28
@alin-at-dfinity
alin-at-dfinity removed this pull request from stack #11604 September 17, 2026 10:21
@alin-at-dfinity
alin-at-dfinity changed the base branch from alin/DSM-148-fake-certified-state to master September 17, 2026 10:47
@alin-at-dfinity
alin-at-dfinity added this pull request to stack #11607 September 17, 2026 10:47
pierugo-dfinity and others added 2 commits September 17, 2026 13:48
Now that #11203 has merged, we can reenable the mainnet NNS recovery
system test.

Due to compatibility reasons, this test must be turned into a "remote"
recovery (which could lead to a few extra minutes of test time) but can
be turned back to "local" once the changes reach mainnet.
Classifies an advertised stream header by how much of its content the pool
already has: accounted for by the cached stream position (`InPayload`), covered
by the pooled slice (`Pooled`), covered by the peer's recorded header
(`Duplicate`), or none of the above (`Actionable`). Content is messages or
signals; or a `begin` far enough along to garbage collect a reject signal of
ours, which is worth fetching on its own, hence the `have_reject_signal_between`
argument.

Also restores `peer_header()` as a plain accessor, for the advert handler and
(later) the advert task to read the recorded headers back.

Nothing calls this yet; the handler follows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread rs/interfaces/src/messaging.rs
Comment thread rs/interfaces/src/messaging.rs
Comment thread rs/xnet/payload_builder/src/certified_slice_pool.rs
Comment thread rs/xnet/payload_builder/src/certified_slice_pool.rs Outdated
Comment thread rs/xnet/payload_builder/tests/certified_slice_pool.rs
Comment thread rs/xnet/payload_builder/tests/certified_slice_pool.rs
Comment thread rs/xnet/payload_builder/tests/certified_slice_pool.rs
@alin-at-dfinity
alin-at-dfinity added this pull request to the merge queue Sep 17, 2026
Merged via the queue into master with commit 9f34f23 Sep 17, 2026
38 checks passed
@alin-at-dfinity
alin-at-dfinity deleted the alin/DSM-148-classify-advert branch September 17, 2026 14:58
Comment on lines +1524 to +1528
header.end() <= messages_end
&& header.signals_end() <= signals_end
// Plus no reject signal of ours left for the advertised `begin` to
// garbage collect.
&& !have_reject_signal_between(header_begin, header.begin())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alin-at-dfinity Unless I missed something, this is not covered by tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are referring to the have_reject_signal_between test, it is covered by pool_classify_advert_collecting_reject_signal(). The (simulated) reject signal at messages_begin (which only the advert covers) vs messages_begin - 1 (which the various references already cover) is the difference between Actionable vs all the other outcomes (depending on which reference we're setting).

Messages and signals are covered by the pool_classify_advert() test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  ┌──────────────────────────────────────────────────────────────────────┬──────────────────────┐
  │               Mutation in certified_slice_pool.rs:1522               │        Result        │
  ├──────────────────────────────────────────────────────────────────────┼──────────────────────┤
  │ header.end() <= messages_end → true                                  │ survives — 23 passed │
  ├──────────────────────────────────────────────────────────────────────┼──────────────────────┤
  │ header.signals_end() <= signals_end → true                           │ survives — 23 passed │
  ├──────────────────────────────────────────────────────────────────────┼──────────────────────┤
  │ !have_reject_signal_between(header_begin, header.begin()) → true     │ caught               │
  ├──────────────────────────────────────────────────────────────────────┼──────────────────────┤
  │ swap args → have_reject_signal_between(header.begin(), header_begin) │ caught               │
  ├──────────────────────────────────────────────────────────────────────┼──────────────────────┤
  │ drop all three X = X.max(Y) accumulations → X = Y                    │ survives — 23 passed │
  └──────────────────────────────────────────────────────────────────────┴──────────────────────┘

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved the unit test coverage. This stack of PRs started off as one monolithic change, so tests were written to cover the whole lot, not just this PR. Although it's quite possible that even so the coverage was more aimed at lines of code (e.g. new signals count as Actionable) rather than all combinations (e.g. new signals compared to the pool contents count as Actionable).

Regardless, improved the coverage.

But in the process, I realized that there was actually a (non-critical) hole in the classification logic. Namely, the messages of a pooled slice may not start from the (cached) expected message index if we just built a payload that did not get selected. So it's not sufficient to look at the messages.end() of a pooled slice, we also need to ensure that messages.begin() extends gap-free whatever we already inducted or put into payloads. So also added that and a test for it.

It's all in #11621.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants