From the dig-node PR#108 adversarial gate (MEDIUM, non-blocking there):
describe_module (module_serve.rs:76-87) does fs::read of the ENTIRE module + SHA-256 of the whole blob + SHA-256 of EVERY chunk, per call. read_module_window reads the entire module for a ≤4 MiB window. There is no descriptor cache and no per-peer rate limit; stream_module_range is paced by the outbound limiter (bytes OUT) but the work is not. So a peer can spam ~100-byte dig.getModuleInfo frames and buy a full-file read + full hashing each time — a large asymmetry.
Mitigating context: the pre-existing local serve already fs::reads the whole module per request (lib.rs:1025/1056), so the read is the established pattern; the genuinely NEW cost is the per-request full hashing.
Task
- Memoize the descriptor keyed by
(path, mtime, len) — cheap and removes the hashing asymmetry entirely.
- Consider metering descriptor requests through the FCFS limiter (work, not just bytes) or a small per-peer request budget.
- Tests: two descriptor requests for an unchanged module hash the file once; a modified module invalidates the memo.
Priority: Medium.
From the dig-node PR#108 adversarial gate (MEDIUM, non-blocking there):
describe_module(module_serve.rs:76-87) doesfs::readof the ENTIRE module + SHA-256 of the whole blob + SHA-256 of EVERY chunk, per call.read_module_windowreads the entire module for a ≤4 MiB window. There is no descriptor cache and no per-peer rate limit;stream_module_rangeis paced by the outbound limiter (bytes OUT) but the work is not. So a peer can spam ~100-bytedig.getModuleInfoframes and buy a full-file read + full hashing each time — a large asymmetry.Mitigating context: the pre-existing local serve already
fs::reads the whole module per request (lib.rs:1025/1056), so the read is the established pattern; the genuinely NEW cost is the per-request full hashing.Task
(path, mtime, len)— cheap and removes the hashing asymmetry entirely.Priority: Medium.