de_mls/app/session/
query.rs1use crate::{
6 app::{ConversationState, MemberRole, SessionRunner, UserError},
7 core::{ConsensusPlugin, ConversationPluginsFactory, PeerScoringPlugin, StewardListPlugin},
8 mls_crypto::MlsService,
9 protos::de_mls::messages::v1::ConversationUpdateRequest,
10};
11
12impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP> {
13 pub fn get_conversation_state(&self) -> ConversationState {
14 self.handle.current_state()
15 }
16
17 pub fn get_epoch_and_retry(&self) -> Result<(u64, u32), UserError> {
21 let epoch = match self.handle.mls() {
22 Some(mls) => mls.current_epoch()?,
23 None => 0,
24 };
25 Ok((epoch, self.handle.steward_list.retry_round()))
26 }
27
28 pub fn get_pending_update_count(&self) -> usize {
32 self.handle.conversation.pending_update_count()
33 }
34
35 pub fn get_freeze_candidate_count(&self) -> (usize, usize) {
38 let received = self.handle.conversation.freeze_candidate_count();
39 let expected = self
40 .handle
41 .steward_list
42 .current_list()
43 .map(|l| l.len())
44 .unwrap_or(0);
45 (received, expected)
46 }
47
48 pub fn is_steward_for_self(&self) -> bool {
49 self.handle.steward_list.is_steward(&self.self_identity)
50 }
51
52 pub fn get_conversation_members(&self) -> Result<Vec<Vec<u8>>, UserError> {
56 match self.handle.mls() {
57 Some(mls) => Ok(mls.members()?),
58 None => Ok(Vec::new()),
59 }
60 }
61
62 pub fn get_member_scores(&self) -> Vec<(Vec<u8>, i64)> {
63 self.handle.scoring.all_members_with_scores()
64 }
65
66 pub fn get_member_score(&self, member_id: &[u8]) -> Option<i64> {
67 self.handle.scoring.score_for(member_id)
68 }
69
70 pub fn get_pending_leave_identities(&self) -> Result<Vec<Vec<u8>>, UserError> {
73 let members = self.handle.expect_mls()?.members()?;
74 Ok(members
75 .into_iter()
76 .filter(|id| self.handle.conversation.is_pending_self_leave(id))
77 .collect())
78 }
79
80 pub fn get_member_roles(&self) -> Result<Vec<(Vec<u8>, MemberRole)>, UserError> {
83 let mls = self.handle.expect_mls()?;
84 let epoch = mls.current_epoch()?;
85 let members = mls.members()?;
86
87 let eligible = self.handle.conversation.steward_eligibility(&members);
88 let (live_epoch, live_backup) = self.handle.steward_list.epoch_and_backup(epoch, &eligible);
89 let live_epoch = live_epoch.map(|s| s.to_vec());
90 let live_backup = live_backup.map(|s| s.to_vec());
91 let exhausted = self.handle.steward_list.is_exhausted(epoch);
92 let has_list = self.handle.steward_list.current_list().is_some();
93 let roles = members
94 .iter()
95 .cloned()
96 .map(|id| {
97 let role = if has_list && !exhausted {
98 if live_epoch.as_deref().is_some_and(|es| es == id) {
99 MemberRole::EpochSteward
100 } else if live_backup.as_deref().is_some_and(|bs| bs == id) {
101 MemberRole::BackupSteward
102 } else if self.handle.steward_list.is_steward(&id) {
103 MemberRole::Steward
104 } else {
105 MemberRole::Member
106 }
107 } else if has_list && self.handle.steward_list.is_steward(&id) {
108 MemberRole::Steward
109 } else {
110 MemberRole::Member
111 };
112 (id, role)
113 })
114 .collect();
115 Ok(roles)
116 }
117
118 pub fn get_approved_proposal_for_current_epoch(&self) -> Vec<ConversationUpdateRequest> {
119 self.handle
120 .conversation
121 .approved_proposals()
122 .values()
123 .cloned()
124 .collect()
125 }
126}