Skip to content

Commit 20f196a

Browse files
committed
causal sorting
1 parent 8d9c7b6 commit 20f196a

File tree

15 files changed

+540
-22
lines changed

15 files changed

+540
-22
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Seeds for failure cases proptest has generated in the past. It is
2+
# automatically read and these particular cases re-run before any
3+
# novel cases are generated.
4+
#
5+
# It is recommended to check this file in to source control so that
6+
# everyone who runs the test benefits from these saved cases.
7+
cc 482a9860cc0bd87984e25141e258ed3dd0a46526ab2987bed337f2a82ac232f8 # shrinks to mut envelopes = [TestEnvelope { cursor: Cursor { originator_id: 10, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 40, sequence_id: 1 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { originator_id: 10, sequence_id: 2 }, depends_on: GlobalCursor { inner: {40: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 40, sequence_id: 2 }, depends_on: GlobalCursor { inner: {10: 2, 40: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 30, sequence_id: 1 }, depends_on: GlobalCursor { inner: {40: 2, 10: 2} } }, TestEnvelope { cursor: Cursor { originator_id: 20, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 1, 30: 1, 40: 2} } }, TestEnvelope { cursor: Cursor { originator_id: 40, sequence_id: 3 }, depends_on: GlobalCursor { inner: {40: 2, 10: 2} } }, TestEnvelope { cursor: Cursor { originator_id: 10, sequence_id: 3 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { originator_id: 20, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 3} } }, TestEnvelope { cursor: Cursor { originator_id: 20, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 3, 40: 3, 20: 1, 30: 1} } }]
8+
cc ef7e3e08b816b5d5754da2da39332f27798cedd3a49cd782a8f74ef59512b093 # shrinks to mut env = EnvelopesWithMissing { missing: [TestEnvelope { cursor: Cursor { originator_id: 20, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 2, 40: 1} } }], envelopes: [TestEnvelope { cursor: Cursor { originator_id: 20, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 2, 40: 1} } }] }
9+
cc 6f3ddf561ffc8eaf9cbef3bd127263538efbc1729b599fa72a7e399d799e23fc # shrinks to mut envelopes = EnvelopesWithMissing { removed: [TestEnvelope { cursor: Cursor { originator_id: 10, sequence_id: 1 }, depends_on: GlobalCursor { inner: {10: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 30, sequence_id: 1 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { originator_id: 40, sequence_id: 1 }, depends_on: GlobalCursor { inner: {} } }], envelopes: [TestEnvelope { cursor: Cursor { originator_id: 10, sequence_id: 2 }, depends_on: GlobalCursor { inner: {40: 1, 10: 1, 30: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 30, sequence_id: 2 }, depends_on: GlobalCursor { inner: {30: 1, 10: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 30, sequence_id: 2 }, depends_on: GlobalCursor { inner: {10: 1, 40: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 40, sequence_id: 2 }, depends_on: GlobalCursor { inner: {10: 2, 40: 1, 30: 2} } }, TestEnvelope { cursor: Cursor { originator_id: 20, sequence_id: 1 }, depends_on: GlobalCursor { inner: {30: 2, 10: 2, 40: 2} } }, TestEnvelope { cursor: Cursor { originator_id: 40, sequence_id: 3 }, depends_on: GlobalCursor { inner: {10: 2, 30: 1, 20: 1, 40: 1} } }, TestEnvelope { cursor: Cursor { originator_id: 30, sequence_id: 3 }, depends_on: GlobalCursor { inner: {30: 2, 20: 1, 10: 2, 40: 2} } }] }
10+
cc d3aa9570c1634dda88771dd96b3bd9ecc3667df1b1202ab686ebe1e49d02e7f0 # shrinks to mut envelopes = EnvelopesWithMissing { removed: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 40 }, depends_on: GlobalCursor { inner: {} } }], envelopes: [TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 1, 40: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 20 }, depends_on: GlobalCursor { inner: {40: 1, 10: 2} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 2, 20: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 20 }, depends_on: GlobalCursor { inner: {40: 1, 10: 3, 20: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {40: 1, 20: 2} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 20 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {20: 3} } }], original: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 40 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 1, 40: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 20 }, depends_on: GlobalCursor { inner: {40: 1, 10: 2} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 2, 20: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 20 }, depends_on: GlobalCursor { inner: {40: 1, 10: 3, 20: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {40: 1, 20: 2} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 20 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {20: 3} } }] }
11+
cc a7823ae07a99a89f88e8382b6515351fd82e6c5fad881286950445e178d87009 # shrinks to mut envelopes = EnvelopesWithMissing { removed: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 10 }, depends_on: GlobalCursor { inner: {40: 1} } }], envelopes: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 40 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 10 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 30 }, depends_on: GlobalCursor { inner: {10: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 2, 30: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {40: 1, 10: 3, 30: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 20 }, depends_on: GlobalCursor { inner: {40: 1, 10: 4} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 20 }, depends_on: GlobalCursor { inner: {10: 4, 30: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 30 }, depends_on: GlobalCursor { inner: {20: 2, 10: 4} } }], original: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 40 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 10 }, depends_on: GlobalCursor { inner: {40: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 10 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 30 }, depends_on: GlobalCursor { inner: {10: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 2, 30: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {40: 1, 10: 3, 30: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 20 }, depends_on: GlobalCursor { inner: {40: 1, 10: 4} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 20 }, depends_on: GlobalCursor { inner: {10: 4, 30: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 30 }, depends_on: GlobalCursor { inner: {20: 2, 10: 4} } }] }
12+
cc 74bdcdf7b3791b00386579747f51d6767fb40b8b4578910bd844a4eec08af6b4 # shrinks to mut envelopes = EnvelopesWithMissing { removed: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 10 }, depends_on: GlobalCursor { inner: {20: 1, 40: 2} } }], envelopes: [TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 30 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 40 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 40 }, depends_on: GlobalCursor { inner: {40: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 30 }, depends_on: GlobalCursor { inner: {30: 1, 40: 1} } }, TestEnvelope { cursor: Cursor { sequence_id: 1, originator_id: 20 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 2, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 1, 40: 2, 20: 1, 30: 2} } }, TestEnvelope { cursor: Cursor { sequence_id: 3, originator_id: 10 }, depends_on: GlobalCursor { inner: {} } }, TestEnvelope { cursor: Cursor { sequence_id: 4, originator_id: 10 }, depends_on: GlobalCursor { inner: {10: 2} } }] }

xmtp_api_d14n/src/protocol/extractors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ mod cursor;
2525
pub use cursor::*;
2626
mod timestamp;
2727
pub use timestamp::*;
28+
mod depends_on;
29+
pub use depends_on::*;
2830

2931
#[cfg(test)]
3032
pub mod test_utils;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Extractor for an MLS Data field
2+
//! useful for verifing a message has been read or maybe duplicates.
3+
use xmtp_proto::ConversionError;
4+
use xmtp_proto::types::GlobalCursor;
5+
use xmtp_proto::xmtp::xmtpv4::envelopes::ClientEnvelope;
6+
7+
use crate::protocol::{EnvelopeVisitor, Extractor};
8+
9+
/// Extract DependsOn from Envelopes
10+
/// If the envelope does not have dependency, or is already
11+
/// ordered (as is the case for v3), then returns `None`.
12+
#[derive(Default, Clone, Debug)]
13+
pub struct DependsOnExtractor {
14+
cursor: Option<GlobalCursor>,
15+
}
16+
17+
impl DependsOnExtractor {
18+
pub fn new() -> Self {
19+
Default::default()
20+
}
21+
}
22+
23+
impl Extractor for DependsOnExtractor {
24+
type Output = Option<GlobalCursor>;
25+
26+
fn get(self) -> Self::Output {
27+
self.cursor
28+
}
29+
}
30+
31+
impl EnvelopeVisitor<'_> for DependsOnExtractor {
32+
type Error = ConversionError;
33+
34+
fn visit_client(&mut self, e: &ClientEnvelope) -> Result<(), Self::Error> {
35+
// to avoid clone here & elsewhere
36+
// https://github.com/xmtp/libxmtp/issues/2691
37+
self.cursor = e
38+
.aad
39+
.as_ref()
40+
.and_then(|a| a.depends_on.clone().map(Into::into));
41+
Ok(())
42+
}
43+
}

xmtp_api_d14n/src/protocol/impls/vector_clock.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashSet;
22

3-
use xmtp_proto::types::{ClockOrdering, GlobalCursor};
3+
use xmtp_proto::types::{ClockOrdering, Cursor, GlobalCursor};
44

55
use crate::protocol::VectorClock;
66

@@ -40,4 +40,13 @@ impl VectorClock for GlobalCursor {
4040
(true, true) => ClockOrdering::Concurrent,
4141
}
4242
}
43+
44+
fn apply(&mut self, cursor: &Cursor) {
45+
let Cursor {
46+
originator_id: node,
47+
sequence_id: seq,
48+
} = &cursor;
49+
let entry = self.entry(*node).or_insert(0);
50+
*entry = (*entry).max(*seq)
51+
}
4352
}

xmtp_api_d14n/src/protocol/sort.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Sorting Implelementations on Envelope Collections [XIP](https://github.com/xmtp/XIPs/blob/main/XIPs/xip-49-decentralized-backend.md#335-cross-originator-message-ordering)
2-
mod casual;
3-
// pub use casual::*;
2+
mod causal;
3+
pub use causal::*;
44
mod timestamp;
55
pub use timestamp::*;

xmtp_api_d14n/src/protocol/sort/casual.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)