xmtp_api_d14n/protocol/traits/sort.rs
1use xmtp_proto::types::{GlobalCursor, TopicCursor};
2
3use crate::protocol::{Envelope, EnvelopeError};
4
5// TODO: sort returns an error because going through the envelopes is
6// fallible b/c deserialization.
7// https://github.com/xmtp/libxmtp/issues/2691 solves this.
8
9/// Envelopes in a d14n-context must be sorted according to its
10/// dependencies, and by-originator.
11/// [XIP, cross-originator sorting](https://github.com/xmtp/XIPs/blob/main/XIPs/xip-49-decentralized-backend.md#335-cross-originator-message-ordering)
12pub trait Sort<Missing> {
13 /// Sort envelopes in-place
14 /// elements remaining in `Self` are guaranteed to be sorted.
15 /// The sort optionally returns `Missing` elements.
16 /// it is up to the caller to resolve any missing envelopes.
17 fn sort(self) -> Result<Option<Missing>, EnvelopeError>;
18}
19
20/// Extension trait to modify a [`TopicCursor`]
21/// with the contents of an envelope.
22pub trait ApplyCursor<E> {
23 /// applies an envelope to a cursor
24 fn apply(&mut self, envelope: &E) -> Result<(), EnvelopeError>;
25}
26
27impl<'a, E: Envelope<'a>> ApplyCursor<E> for TopicCursor {
28 fn apply(&mut self, envelope: &E) -> Result<(), EnvelopeError> {
29 let topic = envelope.topic()?;
30 let cursor = envelope.cursor()?;
31 self.entry(topic)
32 .and_modify(|global| {
33 global.apply(&cursor);
34 })
35 .or_insert_with(|| {
36 let mut map = GlobalCursor::default();
37 map.apply(&cursor);
38 map
39 });
40 Ok(())
41 }
42}