Fork Scenarios in Marmot #27
Replies: 1 comment 1 reply
-
|
I'm still very unconvinced that this is a real issue that isn't handled already by the spec: What the Current Spec Already DoesThe current Marmot spec (MIP-03) addresses commit conflicts with:
When the proposal says:
This is not a realistic scenario under the current protocol. Here's why:
I think that you have correctly identified that clients might not know they've diverged. If Client A only sees Commit X and Client B only sees Commit Y, they each think they're correct. But parent references don't fundamentally solve this - they just let you know "there was a fork" if you see both commits. But if you see both commits - you ALREADY know this. The current tiebreaker already handles this - you apply the winner and discard the other. In the case where you only see one commit: A parent reference doesn't help because you don't know there's another commit to compare against. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
The Hidden Problem in Decentralized Group State
Marmot's current approach handles commit conflicts with a deterministic tiebreaker: earliest timestamp wins, with event ID as final tiebreaker. This works perfectly—until it doesn't. The real danger isn't conflicting commits; it's silent divergence.
Imagine three relays with intermittent connectivity. Admin sends Commit A to Relay A and Commit B to Relay C, both for epoch 5. Clients on Relay A apply Commit A. Clients on Relay C apply Commit B. Both groups think they're at epoch 5, but they have different states. No one knows they've diverged until messages fail to decrypt and users think something is broken.
Why Parent References Matter (And Why They're Not About Ordering)
If two commits reference the same parent, the DAG doesn't tell you which one to choose. You still need a tiebreaker. Parent references don't solve the ordering problem.
But they can solve something crucial: fork detection.
When Commit A and Commit B both reference the same parent, clients can recognize: "This is a fork." Instead of silently choosing one and discarding the other, they can enter a "recovery mode", track both branches temporarily, and make an informed decision based on subsequent activity or protocol conventions.
The 'e' Tag Approach: Lightweight Fork Detection
We can add fork detection with minimal protocol changes by using an
etag in Group Events to reference the previous commit:{ "kind": 445, "tags": [ ["h", "group_id"], ["e", "previous_commit_event_id"] ] }This is backward compatible—old clients ignore it, new clients use it to build a commit graph. The cost is one 64-byte tag per commit.
How Fork Recovery Works in Practice
When a client detects two commits for the same epoch with the same parent reference, it enters a recovery window. During this window:
This turns silent divergence into a temporary, self-healing condition. Other protocol conventions can be applied to determine how to resolve the fork condition, like an admin publishing which branch is current, or any other convention.
Real-World Scenarios
The Three Relay Problem: In a fragmented relay network, different relays may deliver commits in different orders. Without fork detection, clients silently diverge. With parent references, they detect the fork and converge based on actual activity or protocol conventions.
Rapid-Fire Commits: When multiple admins send commits in quick succession, parent references help clients understand the intended order, even if relays deliver them out of sequence.
Benefits of This Approach
For Users: More reliable group messaging, better handling of network issues.
For Developers: Clear protocol for handling edge cases, deterministic behavior, easier debugging of sync issues.
For the Protocol: Moves from best-effort consistency to more robust eventual consistency.
The Key Insight
Timestamps work for ordering, but they don't help you know when you need to order. Parent references give clients the context to recognize forks and the information to recover from them intelligently.
This isn't about replacing the current tiebreaker—it's about detecting when the tiebreaker has created divergence and recovering gracefully.
The cost is minimal (one tag). The benefit is a protocol that handles real-world network conditions rather than assuming perfect relay behavior.
Beta Was this translation helpful? Give feedback.
All reactions