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 }