offline_protocol/constants.rs
1//! Constants used throughout the offline-protocol crate.
2
3/// Default time-to-live for messages.
4pub const DEFAULT_INITIAL_TTL: u8 = 8;
5
6/// Metadata key for ACK messages indicating which message ID the ACK is for.
7///
8/// Re-exported rather than declared, because a leaf node writes the same key on
9/// the acknowledgements it owes and cannot reach this crate. The one home is
10/// `offline-protocol-sealed`; a second spelling here would be a pair that stops
11/// answering each other with nothing failing to build.
12pub use offline_protocol_sealed::ACK_FOR_KEY;
13
14/// Metadata key for ACK messages indicating the hop count.
15pub const ACK_HOP_COUNT_KEY: &str = "ack_hop_count";
16
17/// Metadata key for ACK messages indicating the transport used.
18pub const ACK_TRANSPORT_KEY: &str = "ack_transport";
19
20/// Maximum number of entries in the outbox before evicting oldest entries.
21/// This prevents unbounded memory growth when messages cannot be delivered.
22pub const MAX_OUTBOX_ENTRIES: usize = 500;
23
24/// Absolute cap on a restored outbox entry's total lifetime, as a multiple
25/// of `outbox_max_lifetime_ms`, measured from `first_sent_at`.
26///
27/// The restore path refreshes the carrier-relative TTL of an entry that
28/// lapsed while the process was down (restart ⇒ fresh delivery window).
29/// Without an absolute bound, an app used briefly once past each lifetime
30/// keeps re-granting the entry a fresh window forever, so "expiry is
31/// terminal" would only hold in-process. Past this cap the entry is dropped
32/// at restore with a terminal `message_failed` instead of refreshed
33/// (4 × 7 days = 28 days at the default lifetime).
34pub const OUTBOX_ABSOLUTE_LIFETIME_FACTOR: i32 = 4;
35
36/// Maximum number of messages to keep in history for topology visualization.
37/// This prevents unbounded memory growth while maintaining enough history
38/// for accurate network statistics.
39pub const MAX_MESSAGE_HISTORY: usize = 1000;
40
41/// Number of messages to remove when history exceeds the maximum.
42/// This provides a buffer to avoid frequent cleanup operations.
43pub const HISTORY_CLEANUP_BATCH_SIZE: usize = 100;
44
45/// Threshold for compacting observed stats to prevent unbounded growth.
46pub const OBSERVED_STATS_COMPACT_THRESHOLD: u32 = 10_000;
47
48/// EMA (Exponential Moving Average) alpha for latency tracking.
49pub const LATENCY_EMA_ALPHA: f32 = 0.3;
50
51/// EMA alpha for hop count tracking.
52pub const HOP_COUNT_EMA_ALPHA: f32 = 0.2;
53
54/// Default chunk size for file transfers (32 KB).
55pub const DEFAULT_CHUNK_SIZE: usize = 32 * 1024;
56
57/// Chunk size for BLE file transfers (4 KB).
58/// Reduces BLE double-fragmentation: ~22 BLE fragments per chunk instead of ~240.
59pub const CHUNK_SIZE_BLE: usize = 4 * 1024;
60
61/// Chunk size for Internet file transfers (256 KB).
62/// Fewer round-trips over WebSocket where bandwidth is plentiful.
63pub const CHUNK_SIZE_INTERNET: usize = 256 * 1024;
64
65/// Maximum chunks in flight for BLE media transfers.
66/// BLE's low bandwidth means fewer concurrent chunks to avoid congestion.
67pub const MEDIA_WINDOW_SIZE_BLE: usize = 2;
68
69/// Maximum chunks in flight for Internet media transfers.
70pub const MEDIA_WINDOW_SIZE_INTERNET: usize = 8;
71
72/// Default maximum chunks in flight for media transfers.
73pub const DEFAULT_MEDIA_WINDOW_SIZE: usize = 4;
74
75/// Maximum entries in the dedicated media outbox.
76/// Smaller than the main outbox since the sliding window limits in-flight chunks.
77pub const MAX_MEDIA_OUTBOX_ENTRIES: usize = 100;
78
79/// Maximum persisted outbound media transfer descriptors restored after a
80/// restart (newest-first). Small on purpose: each maps to a
81/// `MediaResendRequired` the app is expected to act on, and concurrent
82/// transfers are already capped per peer.
83pub const MAX_MEDIA_DESCRIPTORS: usize = 16;
84
85/// Maximum concurrent outbound media transfers per recipient when chunks are
86/// MLS-encrypted.
87///
88/// Encrypted chunks share the recipient's 1:1 session ratchet with text, and
89/// the receiver retains out-of-order message keys for only
90/// `SENDER_RATCHET_OUT_OF_ORDER_TOLERANCE` (32) generations. Each transfer
91/// keeps up to `MEDIA_WINDOW_SIZE_INTERNET` (8) chunks in flight, so two
92/// concurrent transfers bound the media-side in-flight gap at 16
93/// generations, leaving room for up to 16 further messages interleaved on
94/// the same ratchet before a delayed chunk's key is deleted. That residual
95/// is not a guarantee: text sends are unbounded, and a chunk delayed while
96/// 32+ interleaved messages decrypt first is permanently undecryptable (the
97/// receiver surfaces this as `MessageDecryptionFailed`). Without this cap,
98/// concurrent transfers alone could push a delayed chunk beyond the
99/// tolerance and permanently stall its transfer.
100pub const MAX_CONCURRENT_MEDIA_TRANSFERS_PER_PEER: usize = 2;
101
102/// How many of a peer's transfer slots the SDK's own document-layer traffic
103/// may occupy at once.
104///
105/// Strictly below [`MAX_CONCURRENT_MEDIA_TRANSFERS_PER_PEER`], and that is
106/// the whole point. A document-layer transfer is invisible to the
107/// application on both sides, so an application whose own `send_media` fails
108/// with [`crate::Error::MediaTransferLimit`] cannot see what is holding the
109/// slots or wait for it to finish. Leaving one slot always reachable keeps
110/// that error explainable by what the application itself is doing.
111pub const MAX_CONCURRENT_INTERNAL_MEDIA_TRANSFERS_PER_PEER: usize = 1;
112
113/// Metadata key indicating preferred transport for a message.
114pub const TRANSPORT_PREFERENCE_KEY: &str = "transport_preference";
115
116/// Transport preference value: prefer internet transport.
117pub const TRANSPORT_PREFERENCE_INTERNET: &str = "internet";
118
119/// Metadata key carrying the original content type on file-chunk messages.
120pub const ORIGINAL_CONTENT_TYPE_KEY: &str = "original_content_type";
121
122/// Maximum number of times a message may be forwarded. Prevents unbounded
123/// forwarding chains from malicious or buggy clients.
124pub const MAX_FORWARD_COUNT: u32 = 100;
125
126/// Maximum messages to send in a single flush operation.
127/// Prevents blocking the process loop when many messages are pending.
128pub const FLUSH_BATCH_LIMIT: usize = 20;