Commit: 2f26d91 · Finding: GEN-08
Problem
crates/client/src/listeners.rs:298-307 calls dag.topological_sort() over the entire DAG on every WireMessage::SyncRequest, then takes only the first 500 entries. topological_sort (crates/state/src/dag.rs:316) iterates every event, builds in-degree + dependents maps, and allocates a Vec of size self.events.len().
For a server with 50k events every sync request pays the full sort cost even though only the first 500 are sent. An N+1 amplifier as peers increase. The in-source TODO acknowledges the temporary nature; the worker has a heads-based sync that should be the migration target (see #65, #207).
Distinct from #65 (protocol change) and #207 (500 cap) — this finding is specifically about the wasted work per request.
Fix
Commit:
2f26d91· Finding:GEN-08Problem
crates/client/src/listeners.rs:298-307callsdag.topological_sort()over the entire DAG on everyWireMessage::SyncRequest, then takes only the first 500 entries.topological_sort(crates/state/src/dag.rs:316) iterates every event, builds in-degree + dependents maps, and allocates a Vec of sizeself.events.len().For a server with 50k events every sync request pays the full sort cost even though only the first 500 are sent. An N+1 amplifier as peers increase. The in-source TODO acknowledges the temporary nature; the worker has a
heads-based sync that should be the migration target (see #65, #207).Distinct from #65 (protocol change) and #207 (500 cap) — this finding is specifically about the wasted work per request.
Fix
WorkerRequest::Sync { heads }— see Worker sync protocol uses bulk SyncBatch instead of per-author Advertise/Request/Response #65.