Skip to content

fix(peer): enforce the #30 egress budget on the module-range serve path - #137

Merged
MichaelTaylor3d merged 1 commit into
mainfrom
fix/1616-module-range-egress-budget
Aug 2, 2026
Merged

fix(peer): enforce the #30 egress budget on the module-range serve path#137
MichaelTaylor3d merged 1 commit into
mainfrom
fix/1616-module-range-egress-budget

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

What changed

stream_module_range — the whole-capsule dig.fetchModuleRange serve, the largest transfer in the system — consulted only the FCFS serve_limiter and recorded outgoing bytes, but never consulted the operator-configured #30 egress budget the way stream_range does (bandwidth_redirect / would_exceed). An operator's configured egress cap was silently bypassed on exactly the path where it matters most.

This adds the same budget gate stream_range uses, checked once before the first frame against the window this stream will actually serve:

  • Over budget + a known alternate holder → decline with the redirect frame ({"error": …} with data.redirect) — the same shape the not-held answer already emits, which the module-range puller (read_module_window) handles by sourcing the window from another provider.
  • Over budget + no alternatebandwidth_redirect returns None, so serve anyway (never drop a request only this node can answer).
  • Under budget / no throttle → stream unchanged.

Semantics are identical to stream_range. The capsule-granularity ContentId::capsule(store, root) is used for the provider lookup.

Why this is wire-safe

The decline reuses the exact mechanism the not-held path already uses in production (write_framed(out, &{"error": …})): the reshare/module-pull puller already treats such a frame as "this holder can't serve → try another provider." No change to the frame wire or the puller.

Blast radius (gitnexus/manual)

stream_module_range (peer.rs) only — the change is a pre-stream guard. The puller (module_transport::read_module_window) is unchanged and already handles the {"error": …} decline. bandwidth_redirect and availability_content_id are reused unchanged.

Verification

  • New tests (mutation-verified):
    • stream_module_range_over_cap_with_a_provider_declines_instead_of_streaming — over the 10-byte cap with a known capsule provider, the serve returns the CONTENT_REDIRECT frame naming the provider. Confirmed to FAIL when the guard is removed (it otherwise streams).
    • stream_module_range_over_cap_with_no_provider_still_streams — over the cap with no known holder, the module window streams anyway.
  • cargo fmt --all -- --check clean · cargo clippy -p dig-node-core --all-targets --all-features -D warnings clean.

Note: stream_range's PR#108 body claimed the module path was "paced by the same limiter" — true only of the FCFS limiter, not the #30 egress budget; this closes that gap.

Version

fix: → patch bump [workspace.package].version 0.72.6 → 0.72.7.

Closes #1616.


Generated by Claude Code

@MichaelTaylor3d
MichaelTaylor3d force-pushed the fix/1616-module-range-egress-budget branch from 3d1df61 to 6d68ad1 Compare August 2, 2026 06:35
stream_module_range (the whole-capsule dig.fetchModuleRange serve — the
largest transfer in the system) consulted only the FCFS serve_limiter and
recorded outgoing bytes, but never consulted the operator-configured #30
egress budget the way stream_range does. So a configured egress cap was
silently bypassed on exactly the path where it matters most.

Check bandwidth_redirect once before the first frame, against the window
this stream will actually serve: over budget with a known alternate holder,
decline with the redirect frame (same {"error": …} shape the not-held
answer already uses, which the puller handles by sourcing the window
elsewhere); no alternate holder, serve anyway (never drop a request only
this node can answer) — identical semantics to stream_range.

Tests (mutation-verified): over-cap + a known provider declines/redirects;
over-cap + no provider still streams the window.

Closes #1616

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d force-pushed the fix/1616-module-range-egress-budget branch from 6d68ad1 to 60488cd Compare August 2, 2026 07:04
@MichaelTaylor3d
MichaelTaylor3d merged commit f5e3b09 into main Aug 2, 2026
15 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the fix/1616-module-range-egress-budget branch August 2, 2026 07:22
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