Skip to main content

iris_chat_protocol/protocol_engine/
notification_preview.rs

1use super::*;
2
3// Discard outgoing work during decoding, before allocating copies of its bodies.
4// Authentication evidence and incoming recovery queues retain the ordinary
5// decoder and migration rules. This view must never replace the live checkpoint.
6#[derive(Deserialize)]
7pub(super) struct NotificationPreviewPersistedState {
8    #[serde(default, rename = "pending_group_fanouts")]
9    _fanouts: serde::de::IgnoredAny,
10    #[serde(default, rename = "ready_group_publications")]
11    _publications: serde::de::IgnoredAny,
12    #[serde(default, rename = "pending_local_sibling_sends")]
13    _sibling_sends: serde::de::IgnoredAny,
14    #[serde(default, rename = "pending_remote_sends")]
15    _remote_sends: serde::de::IgnoredAny,
16    #[serde(flatten)]
17    pub(super) state: ProtocolEnginePersistedState,
18}
19
20impl ProtocolEngine {
21    /// Load an ephemeral receive preview without initializing an account,
22    /// loading outgoing queues, or writing a startup checkpoint. Callers must
23    /// provide an isolated storage overlay for any legacy migration writes and
24    /// discard the engine after use; do not finish its batch or use it to send.
25    pub fn load_for_notification_preview(
26        storage: Arc<dyn StorageAdapter>,
27        owner_pubkey: PublicKey,
28        device_keys: &Keys,
29    ) -> anyhow::Result<Option<Self>> {
30        let Some(engine) = Self::load_persisted_state(
31            storage,
32            owner_pubkey,
33            ndr_owner(owner_pubkey),
34            ndr_device(device_keys.public_key()),
35            device_keys.secret_key().to_secret_bytes(),
36            true,
37        )?
38        else {
39            return Ok(None);
40        };
41        // The ordinary constructor persists before returning. Starting the
42        // batch here avoids materializing the entire backlog in a short-lived
43        // iOS notification process, including on its first received event.
44        engine.enter_batch();
45        Ok(Some(engine))
46    }
47}