-
Notifications
You must be signed in to change notification settings - Fork 23
Description
eventStore (Sembast) accumulates events indefinitely. When SessionNotifier._cleanup() removes expired sessions (after 72h), the associated events in eventStore are never deleted. The only way events are removed is through full-reset operations (user restore or key reset), which wipe the entire store.
Sources of accumulation
Three writers append to eventStore:
| Writer | Type tag | What's stored | Size per event |
|---|---|---|---|
MostroService._onData() |
(none) | id + created_at only |
~100 bytes |
ChatRoomNotifier._onChatEvent() / sendMessage() |
'chat' |
Full gift wrap event (encrypted content, tags, sig, pubkey) | ~1-5 KB |
DisputeChatNotifier._onChatEvent() / sendMessage() |
'dispute_chat' |
Full gift wrap event | ~1-5 KB |
Why nothing gets cleaned up
SessionNotifier._cleanup() runs every 30 minutes and deletes sessions older than 72h from sessionStorage:
void _cleanup() async {
final cutoff = DateTime.now()
.subtract(const Duration(hours: Config.sessionExpirationHours));
for (final session in expiredSessions) {
if (session.startTime.isBefore(cutoff)) {
await _storage.deleteSession(session.orderId!); // only sessionStorage
_sessions.remove(session.orderId!);
}
}
}
It never touches eventStore. The chat/dispute events for that orderId remain in the database forever.
The only two deletion paths are full wipes:
RestoreManager._clearAll()→eventStorageProvider.deleteAll()KeyManagementScreen (reset identity)→eventStorage.deleteAll()
Impact
- Low-frequency users: Negligible, a few dozen events per trade, a few trades per month
- High-frequency users over months: Unbounded growth of encrypted blobs in Sembast. No upper limit.
- MostroService dedup entries: Every Mostro protocol event (order updates, state changes) adds a stub entry (
id+created_at) that is never cleaned up, even after the order is long gone
Suggested fix
When SessionNotifier._cleanup() deletes an expired session, also delete its associated events:
After deleting the session:
final eventStore = ref.read(eventStorageProvider);
await eventStore.deleteWhere(Filter.equals('order_id', session.orderId));
For MostroService dedup entries (which have no order_id or type field), a created_at-based cleanup could be added:
Periodically remove dedup stubs older than session expiration
await eventStore.deleteWhere(
Filter.and([
Filter.notEquals('type', 'chat'),
Filter.notEquals('type', 'dispute_chat'),
Filter.lessThan('created_at', cutoffTimestamp),
]),
);
Additional context
- Config.sessionExpirationHours = 72
- Config.cleanupIntervalMinutes = 30
- BaseStorage already has deleteWhere(Filter), no new infrastructure needed
- Chat and dispute events are tagged with
order_id, making selective deletion straightforward