Skip to content

No idempotency: Duplicate messages on network redelivery #10

@rafabd1

Description

@rafabd1

The protocol has no duplicate detection. If a message is retransmitted on the I2P network (e.g., due to timeout+retry), it will be stored twice:

Wire format (messaging.rs:19-24):

struct WireMessage {
    t: &str,      // type ("msg")
    id: &str,     // UUID (unique)
    ct: String,   // ciphertext
    n: u32,       // ratchet counter
}

Problem: While id is unique per message sent, there's no idempotency check on receive:

let entry = MessageEntry {
    id: wire.id.clone(),
    // ...
};
state.messages.lock().await.push(entry);  // No check if id already exists!

Failure scenario:

  1. Peer sends message with id="abc123", counter=42
  2. Network delivers it, peer doesn't get ACK immediately
  3. Peer retransmits with same id, counter=42
  4. We receive both → push both to state.messages
  5. User sees the same message twice in the UI

Why this matters:

  • I2P doesn't guarantee delivery, apps must handle retransmissions
  • User sees duplicate messages
  • Can break message count expectations
  • TTL expiration tracking gets confused

Proposed solution:

  • Keep a set of recently seen message IDs (with TTL)
  • Deduplicate on receive: if id already in messages, skip or update
  • Or: explicit ACK mechanism (peer sends "msg_ack" with message id)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions