tests.rs
1 use super::*; 2 3 use crate::core::{build_key_package_message, create_group, prepare_to_join, process_inbound}; 4 use crate::ds::WELCOME_SUBTOPIC; 5 use crate::mls_crypto::{MemoryDeMlsStorage, MlsService, parse_wallet_address}; 6 7 fn setup_mls(wallet_hex: &str) -> MlsService<MemoryDeMlsStorage> { 8 let storage = MemoryDeMlsStorage::new(); 9 let mls = MlsService::new(storage); 10 let wallet = parse_wallet_address(wallet_hex).unwrap(); 11 mls.init(wallet).unwrap(); 12 mls 13 } 14 15 fn setup_steward( 16 group_name: &str, 17 wallet_hex: &str, 18 ) -> (MlsService<MemoryDeMlsStorage>, GroupHandle) { 19 let mls = setup_mls(wallet_hex); 20 let handle = create_group(group_name, &mls).unwrap(); 21 (mls, handle) 22 } 23 24 fn setup_joiner( 25 group_name: &str, 26 wallet_hex: &str, 27 ) -> (MlsService<MemoryDeMlsStorage>, GroupHandle, OutboundPacket) { 28 let mls = setup_mls(wallet_hex); 29 let handle = prepare_to_join(group_name); 30 let kp_packet = build_key_package_message(&handle, &mls, b"test-app-id").unwrap(); 31 (mls, handle, kp_packet) 32 } 33 34 fn steward_add_joiner( 35 steward_mls: &MlsService<MemoryDeMlsStorage>, 36 steward_handle: &mut GroupHandle, 37 joiner_kp_packet: &OutboundPacket, 38 ) -> (OutboundPacket, OutboundPacket) { 39 use std::sync::atomic::{AtomicU32, Ordering}; 40 static PROPOSAL_COUNTER: AtomicU32 = AtomicU32::new(200); 41 42 let result = process_inbound( 43 steward_handle, 44 &joiner_kp_packet.payload, 45 WELCOME_SUBTOPIC, 46 steward_mls, 47 ) 48 .unwrap(); 49 50 let gur = match result { 51 ProcessResult::GetUpdateRequest(gur) => gur, 52 other => panic!("Expected GetUpdateRequest, got {:?}", other), 53 }; 54 55 let proposal_id = PROPOSAL_COUNTER.fetch_add(1, Ordering::Relaxed); 56 steward_handle.insert_approved_proposal(proposal_id, gur); 57 let app_id = b"test-app-id"; 58 let packets = create_commit_candidate(steward_handle, steward_mls, app_id).unwrap(); 59 60 let finalize = finalize_freeze_round(steward_handle, steward_mls, false, app_id).unwrap(); 61 let welcome_packet = match finalize { 62 FreezeFinalizeResult::Applied { result, outbound } => { 63 assert!( 64 matches!(result, ProcessResult::GroupUpdated), 65 "Expected GroupUpdated, got {:?}", 66 result 67 ); 68 outbound 69 .into_iter() 70 .find(|p| p.subtopic == WELCOME_SUBTOPIC) 71 .expect("Expected deferred welcome packet from finalize_freeze_round") 72 } 73 other => panic!("Expected Applied, got {:?}", other), 74 }; 75 76 let batch_packet = packets 77 .iter() 78 .find(|p| p.subtopic == APP_MSG_SUBTOPIC) 79 .expect("Expected batch proposals packet") 80 .clone(); 81 82 (welcome_packet, batch_packet) 83 } 84 85 #[test] 86 fn test_validate_batch_proposals_action_mismatch() { 87 let group_name = "validate-action-mismatch"; 88 let (steward_mls, mut steward_handle) = 89 setup_steward(group_name, "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); 90 let (joiner_mls, mut joiner_handle, kp_packet) = 91 setup_joiner(group_name, "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"); 92 93 let (welcome_packet, _) = steward_add_joiner(&steward_mls, &mut steward_handle, &kp_packet); 94 process_inbound( 95 &mut joiner_handle, 96 &welcome_packet.payload, 97 WELCOME_SUBTOPIC, 98 &joiner_mls, 99 ) 100 .unwrap(); 101 102 let (_joiner2_mls, _joiner2_handle, kp2_packet) = 103 setup_joiner(group_name, "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"); 104 let result = process_inbound( 105 &mut steward_handle, 106 &kp2_packet.payload, 107 WELCOME_SUBTOPIC, 108 &steward_mls, 109 ) 110 .unwrap(); 111 let gur = match result { 112 ProcessResult::GetUpdateRequest(gur) => gur, 113 other => panic!("Expected GetUpdateRequest, got {:?}", other), 114 }; 115 116 let proposal_id: ProposalId = 43; 117 joiner_handle.insert_approved_proposal(proposal_id, gur); 118 119 let steward_id = steward_handle.steward_identity().unwrap().to_vec(); 120 let local_proposals = joiner_handle.approved_proposals(); 121 122 // Pass wrong MLS actions (empty) while local has an add proposal 123 let result = validate_commit_candidate( 124 &joiner_handle, 125 &local_proposals, 126 &steward_id, 127 &[], // empty actions, should mismatch 128 ) 129 .unwrap(); 130 131 match result { 132 Some(ProcessResult::ViolationDetected(evidence)) => { 133 use crate::protos::de_mls::messages::v1::ViolationType; 134 assert_eq!( 135 evidence.violation_type, 136 ViolationType::BrokenMlsProposal as i32 137 ); 138 } 139 other => panic!("Expected Some(ViolationDetected), got {:?}", other), 140 } 141 }