/ src / core / proposal_priority.rs
proposal_priority.rs
 1  //! Proposal priority for consensus proposals.
 2  //!
 3  //! Emergency criteria proposals have the highest priority. When a higher-priority
 4  //! proposal is active and not yet finalized, lower-priority proposals should be
 5  //! deferred.
 6  
 7  use crate::protos::de_mls::messages::v1::{GroupUpdateRequest, group_update_request};
 8  
 9  /// Priority levels for consensus proposals (higher value = higher priority).
10  ///
11  /// When a proposal of a given priority is active, proposals of
12  /// strictly lower priority should be dropped or deferred.
13  #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14  pub enum ProposalPriority {
15      /// Commit proposals (add/remove member) — lowest priority.
16      Commit = 0,
17      /// Emergency criteria proposals — highest priority.
18      Emergency = 2,
19  }
20  
21  impl ProposalPriority {
22      /// Determine the priority of a `GroupUpdateRequest` based on its payload.
23      pub fn from_request(request: &GroupUpdateRequest) -> Self {
24          match &request.payload {
25              Some(group_update_request::Payload::EmergencyCriteria(_)) => {
26                  ProposalPriority::Emergency
27              }
28              _ => ProposalPriority::Commit,
29          }
30      }
31  }
32  
33  #[cfg(test)]
34  mod tests {
35      use super::*;
36      use crate::protos::de_mls::messages::v1::{
37          EmergencyCriteriaProposal, InviteMember, RemoveMember, ViolationEvidence,
38      };
39  
40      #[test]
41      fn test_invite_member_is_commit_priority() {
42          let request = GroupUpdateRequest {
43              payload: Some(group_update_request::Payload::InviteMember(InviteMember {
44                  key_package_bytes: vec![],
45                  identity: vec![],
46              })),
47          };
48          assert_eq!(
49              ProposalPriority::from_request(&request),
50              ProposalPriority::Commit
51          );
52      }
53  
54      #[test]
55      fn test_remove_member_is_commit_priority() {
56          let request = GroupUpdateRequest {
57              payload: Some(group_update_request::Payload::RemoveMember(RemoveMember {
58                  identity: vec![],
59              })),
60          };
61          assert_eq!(
62              ProposalPriority::from_request(&request),
63              ProposalPriority::Commit
64          );
65      }
66  
67      #[test]
68      fn test_emergency_criteria_is_emergency_priority() {
69          let request = GroupUpdateRequest {
70              payload: Some(group_update_request::Payload::EmergencyCriteria(
71                  EmergencyCriteriaProposal {
72                      evidence: Some(ViolationEvidence::broken_commit(vec![], 0, vec![])),
73                  },
74              )),
75          };
76          assert_eq!(
77              ProposalPriority::from_request(&request),
78              ProposalPriority::Emergency
79          );
80      }
81  
82      #[test]
83      fn test_emergency_is_higher_than_commit() {
84          assert!(ProposalPriority::Emergency > ProposalPriority::Commit);
85      }
86  }