diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-09 09:24:17 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-09 09:24:17 +0000 |
| commit | eb10e85f199266affd3bca0a3d4cd934f74f3e7f (patch) | |
| tree | 8a09f93658be462bfb8196670195f1b8748c2183 /src/sync/algorithms.rs | |
| parent | e1806540b5d905646b786e21a6060e4498e9aff1 (diff) | |
feat(sync): prevent infinite retry loop in negentropy validation
Add retry protection to negentropy event validation:
- Track retry_count in PendingBatch (incremented on each retry attempt)
- Detect when retry makes zero progress (relay returns no requested events)
- Abort retry and complete batch with partial results when stuck
- Log error with full details when retry protection triggers
This prevents infinite loops when:
- Relay has bugs and returns wrong events for ID queries
- Relay is malicious and returns unrelated events
- Relay has eventual consistency issues
- Network corruption causes incorrect responses
The protection triggers when received_count == 0 on a retry (relay
returned nothing we asked for), indicating the relay will never
provide the missing events.
Future work: Track failed batches in Prometheus metrics
(sync_failed_batches_total) for monitoring and alerting.
Diffstat (limited to 'src/sync/algorithms.rs')
| -rw-r--r-- | src/sync/algorithms.rs | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/src/sync/algorithms.rs b/src/sync/algorithms.rs index 4679986..e083dc8 100644 --- a/src/sync/algorithms.rs +++ b/src/sync/algorithms.rs | |||
| @@ -404,6 +404,7 @@ mod tests { | |||
| 404 | pagination_state: HashMap::new(), | 404 | pagination_state: HashMap::new(), |
| 405 | requested_event_ids: None, | 405 | requested_event_ids: None, |
| 406 | received_event_ids: None, | 406 | received_event_ids: None, |
| 407 | retry_count: 0, | ||
| 407 | }], | 408 | }], |
| 408 | ); | 409 | ); |
| 409 | 410 | ||
| @@ -518,6 +519,7 @@ mod tests { | |||
| 518 | pagination_state: HashMap::new(), | 519 | pagination_state: HashMap::new(), |
| 519 | requested_event_ids: None, | 520 | requested_event_ids: None, |
| 520 | received_event_ids: None, | 521 | received_event_ids: None, |
| 522 | retry_count: 0, | ||
| 521 | }], | 523 | }], |
| 522 | ); | 524 | ); |
| 523 | 525 | ||