fix: sending slowness
This commit is contained in:
		
							parent
							
								
									0b263208e3
								
							
						
					
					
						commit
						b7ab57897b
					
				
					 15 changed files with 574 additions and 417 deletions
				
			
		
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							|  | @ -1831,7 +1831,7 @@ checksum = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" | ||||||
| [[package]] | [[package]] | ||||||
| name = "state-res" | name = "state-res" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| source = "git+https://github.com/timokoesters/state-res?branch=spec-comp#a9186476b748c901fbf4356414247a0b3ac01b5f" | source = "git+https://github.com/timokoesters/state-res?branch=spec-comp#1d01b6e65b6afd50e65085fb40f1e7d2782f519e" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "itertools", |  "itertools", | ||||||
|  "js_int", |  "js_int", | ||||||
|  |  | ||||||
|  | @ -354,19 +354,23 @@ pub async fn deactivate_route( | ||||||
|             third_party_invite: None, |             third_party_invite: None, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type: EventType::RoomMember, |                 PduBuilder { | ||||||
|                 content: serde_json::to_value(event).expect("event is valid, we just created it"), |                     event_type: EventType::RoomMember, | ||||||
|                 unsigned: None, |                     content: serde_json::to_value(event) | ||||||
|                 state_key: Some(sender_id.to_string()), |                         .expect("event is valid, we just created it"), | ||||||
|                 redacts: None, |                     unsigned: None, | ||||||
|             }, |                     state_key: Some(sender_id.to_string()), | ||||||
|             &sender_id, |                     redacts: None, | ||||||
|             &room_id, |                 }, | ||||||
|             &db.globals, |                 &sender_id, | ||||||
|             &db.account_data, |                 &room_id, | ||||||
|         ).await?; |                 &db.globals, | ||||||
|  |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Remove devices and mark account as deactivated
 |     // Remove devices and mark account as deactivated
 | ||||||
|  |  | ||||||
|  | @ -120,6 +120,7 @@ pub async fn leave_room_route( | ||||||
|             &sender_id, |             &sender_id, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             &db.globals, |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|             &db.account_data, |             &db.account_data, | ||||||
|         ) |         ) | ||||||
|         .await?; |         .await?; | ||||||
|  | @ -157,6 +158,7 @@ pub async fn invite_user_route( | ||||||
|                 &sender_id, |                 &sender_id, | ||||||
|                 &body.room_id, |                 &body.room_id, | ||||||
|                 &db.globals, |                 &db.globals, | ||||||
|  |                 &db.sending, | ||||||
|                 &db.account_data, |                 &db.account_data, | ||||||
|             ) |             ) | ||||||
|             .await?; |             .await?; | ||||||
|  | @ -209,6 +211,7 @@ pub async fn kick_user_route( | ||||||
|             &sender_id, |             &sender_id, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             &db.globals, |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|             &db.account_data, |             &db.account_data, | ||||||
|         ) |         ) | ||||||
|         .await?; |         .await?; | ||||||
|  | @ -266,6 +269,7 @@ pub async fn ban_user_route( | ||||||
|             &sender_id, |             &sender_id, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             &db.globals, |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|             &db.account_data, |             &db.account_data, | ||||||
|         ) |         ) | ||||||
|         .await?; |         .await?; | ||||||
|  | @ -314,6 +318,7 @@ pub async fn unban_user_route( | ||||||
|             &sender_id, |             &sender_id, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             &db.globals, |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|             &db.account_data, |             &db.account_data, | ||||||
|         ) |         ) | ||||||
|         .await?; |         .await?; | ||||||
|  | @ -672,6 +677,7 @@ async fn join_room_by_id_helper( | ||||||
|                 &sender_id, |                 &sender_id, | ||||||
|                 &room_id, |                 &room_id, | ||||||
|                 &db.globals, |                 &db.globals, | ||||||
|  |                 &db.sending, | ||||||
|                 &db.account_data, |                 &db.account_data, | ||||||
|             ) |             ) | ||||||
|             .await?; |             .await?; | ||||||
|  |  | ||||||
|  | @ -49,25 +49,29 @@ pub async fn send_message_event_route( | ||||||
|     let mut unsigned = serde_json::Map::new(); |     let mut unsigned = serde_json::Map::new(); | ||||||
|     unsigned.insert("transaction_id".to_owned(), body.txn_id.clone().into()); |     unsigned.insert("transaction_id".to_owned(), body.txn_id.clone().into()); | ||||||
| 
 | 
 | ||||||
|     let event_id = db.rooms.build_and_append_pdu( |     let event_id = db | ||||||
|         PduBuilder { |         .rooms | ||||||
|             event_type: body.content.event_type().into(), |         .build_and_append_pdu( | ||||||
|             content: serde_json::from_str( |             PduBuilder { | ||||||
|                 body.json_body |                 event_type: body.content.event_type().into(), | ||||||
|                     .as_ref() |                 content: serde_json::from_str( | ||||||
|                     .ok_or(Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))? |                     body.json_body | ||||||
|                     .get(), |                         .as_ref() | ||||||
|             ) |                         .ok_or(Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))? | ||||||
|             .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?, |                         .get(), | ||||||
|             unsigned: Some(unsigned), |                 ) | ||||||
|             state_key: None, |                 .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?, | ||||||
|             redacts: None, |                 unsigned: Some(unsigned), | ||||||
|         }, |                 state_key: None, | ||||||
|         &sender_id, |                 redacts: None, | ||||||
|         &body.room_id, |             }, | ||||||
|         &db.globals, |             &sender_id, | ||||||
|         &db.account_data, |             &body.room_id, | ||||||
|     ).await?; |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     db.transaction_ids |     db.transaction_ids | ||||||
|         .add_txnid(sender_id, device_id, &body.txn_id, event_id.as_bytes())?; |         .add_txnid(sender_id, device_id, &body.txn_id, event_id.as_bytes())?; | ||||||
|  |  | ||||||
|  | @ -31,40 +31,43 @@ pub async fn set_displayname_route( | ||||||
|     // Send a new membership event and presence update into all joined rooms
 |     // Send a new membership event and presence update into all joined rooms
 | ||||||
|     for room_id in db.rooms.rooms_joined(&sender_id) { |     for room_id in db.rooms.rooms_joined(&sender_id) { | ||||||
|         let room_id = room_id?; |         let room_id = room_id?; | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type: EventType::RoomMember, |                 PduBuilder { | ||||||
|                 content: serde_json::to_value(ruma::events::room::member::MemberEventContent { |                     event_type: EventType::RoomMember, | ||||||
|                     displayname: body.displayname.clone(), |                     content: serde_json::to_value(ruma::events::room::member::MemberEventContent { | ||||||
|                     ..serde_json::from_value::<Raw<_>>( |                         displayname: body.displayname.clone(), | ||||||
|                         db.rooms |                         ..serde_json::from_value::<Raw<_>>( | ||||||
|                             .room_state_get( |                             db.rooms | ||||||
|                                 &room_id, |                                 .room_state_get( | ||||||
|                                 &EventType::RoomMember, |                                     &room_id, | ||||||
|                                 &sender_id.to_string(), |                                     &EventType::RoomMember, | ||||||
|                             )? |                                     &sender_id.to_string(), | ||||||
|                             .ok_or_else(|| { |                                 )? | ||||||
|                                 Error::bad_database( |                                 .ok_or_else(|| { | ||||||
|  |                                     Error::bad_database( | ||||||
|                                     "Tried to send displayname update for user not in the room.", |                                     "Tried to send displayname update for user not in the room.", | ||||||
|                                 ) |                                 ) | ||||||
|                             })? |                                 })? | ||||||
|                             .content |                                 .content | ||||||
|                             .clone(), |                                 .clone(), | ||||||
|                     ) |                         ) | ||||||
|                     .expect("from_value::<Raw<..>> can never fail") |                         .expect("from_value::<Raw<..>> can never fail") | ||||||
|                     .deserialize() |                         .deserialize() | ||||||
|                     .map_err(|_| Error::bad_database("Database contains invalid PDU."))? |                         .map_err(|_| Error::bad_database("Database contains invalid PDU."))? | ||||||
|                 }) |                     }) | ||||||
|                 .expect("event is valid, we just created it"), |                     .expect("event is valid, we just created it"), | ||||||
|                 unsigned: None, |                     unsigned: None, | ||||||
|                 state_key: Some(sender_id.to_string()), |                     state_key: Some(sender_id.to_string()), | ||||||
|                 redacts: None, |                     redacts: None, | ||||||
|             }, |                 }, | ||||||
|             &sender_id, |                 &sender_id, | ||||||
|             &room_id, |                 &room_id, | ||||||
|             &db.globals, |                 &db.globals, | ||||||
|             &db.account_data, |                 &db.sending, | ||||||
|         ).await?; |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
| 
 | 
 | ||||||
|         // Presence update
 |         // Presence update
 | ||||||
|         db.rooms.edus.update_presence( |         db.rooms.edus.update_presence( | ||||||
|  | @ -134,40 +137,43 @@ pub async fn set_avatar_url_route( | ||||||
|     // Send a new membership event and presence update into all joined rooms
 |     // Send a new membership event and presence update into all joined rooms
 | ||||||
|     for room_id in db.rooms.rooms_joined(&sender_id) { |     for room_id in db.rooms.rooms_joined(&sender_id) { | ||||||
|         let room_id = room_id?; |         let room_id = room_id?; | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type: EventType::RoomMember, |                 PduBuilder { | ||||||
|                 content: serde_json::to_value(ruma::events::room::member::MemberEventContent { |                     event_type: EventType::RoomMember, | ||||||
|                     avatar_url: body.avatar_url.clone(), |                     content: serde_json::to_value(ruma::events::room::member::MemberEventContent { | ||||||
|                     ..serde_json::from_value::<Raw<_>>( |                         avatar_url: body.avatar_url.clone(), | ||||||
|                         db.rooms |                         ..serde_json::from_value::<Raw<_>>( | ||||||
|                             .room_state_get( |                             db.rooms | ||||||
|                                 &room_id, |                                 .room_state_get( | ||||||
|                                 &EventType::RoomMember, |                                     &room_id, | ||||||
|                                 &sender_id.to_string(), |                                     &EventType::RoomMember, | ||||||
|                             )? |                                     &sender_id.to_string(), | ||||||
|                             .ok_or_else(|| { |                                 )? | ||||||
|                                 Error::bad_database( |                                 .ok_or_else(|| { | ||||||
|                                     "Tried to send avatar url update for user not in the room.", |                                     Error::bad_database( | ||||||
|                                 ) |                                         "Tried to send avatar url update for user not in the room.", | ||||||
|                             })? |                                     ) | ||||||
|                             .content |                                 })? | ||||||
|                             .clone(), |                                 .content | ||||||
|                     ) |                                 .clone(), | ||||||
|                     .expect("from_value::<Raw<..>> can never fail") |                         ) | ||||||
|                     .deserialize() |                         .expect("from_value::<Raw<..>> can never fail") | ||||||
|                     .map_err(|_| Error::bad_database("Database contains invalid PDU."))? |                         .deserialize() | ||||||
|                 }) |                         .map_err(|_| Error::bad_database("Database contains invalid PDU."))? | ||||||
|                 .expect("event is valid, we just created it"), |                     }) | ||||||
|                 unsigned: None, |                     .expect("event is valid, we just created it"), | ||||||
|                 state_key: Some(sender_id.to_string()), |                     unsigned: None, | ||||||
|                 redacts: None, |                     state_key: Some(sender_id.to_string()), | ||||||
|             }, |                     redacts: None, | ||||||
|             &sender_id, |                 }, | ||||||
|             &room_id, |                 &sender_id, | ||||||
|             &db.globals, |                 &room_id, | ||||||
|             &db.account_data, |                 &db.globals, | ||||||
|         ).await?; |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
| 
 | 
 | ||||||
|         // Presence update
 |         // Presence update
 | ||||||
|         db.rooms.edus.update_presence( |         db.rooms.edus.update_presence( | ||||||
|  |  | ||||||
|  | @ -18,22 +18,26 @@ pub async fn redact_event_route( | ||||||
| ) -> ConduitResult<redact_event::Response> { | ) -> ConduitResult<redact_event::Response> { | ||||||
|     let sender_id = body.sender_id.as_ref().expect("user is authenticated"); |     let sender_id = body.sender_id.as_ref().expect("user is authenticated"); | ||||||
| 
 | 
 | ||||||
|     let event_id = db.rooms.build_and_append_pdu( |     let event_id = db | ||||||
|         PduBuilder { |         .rooms | ||||||
|             event_type: EventType::RoomRedaction, |         .build_and_append_pdu( | ||||||
|             content: serde_json::to_value(redaction::RedactionEventContent { |             PduBuilder { | ||||||
|                 reason: body.reason.clone(), |                 event_type: EventType::RoomRedaction, | ||||||
|             }) |                 content: serde_json::to_value(redaction::RedactionEventContent { | ||||||
|             .expect("event is valid, we just created it"), |                     reason: body.reason.clone(), | ||||||
|             unsigned: None, |                 }) | ||||||
|             state_key: None, |                 .expect("event is valid, we just created it"), | ||||||
|             redacts: Some(body.event_id.clone()), |                 unsigned: None, | ||||||
|         }, |                 state_key: None, | ||||||
|         &sender_id, |                 redacts: Some(body.event_id.clone()), | ||||||
|         &body.room_id, |             }, | ||||||
|         &db.globals, |             &sender_id, | ||||||
|         &db.account_data, |             &body.room_id, | ||||||
|     ).await?; |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     Ok(redact_event::Response { event_id }.into()) |     Ok(redact_event::Response { event_id }.into()) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -53,41 +53,47 @@ pub async fn create_room_route( | ||||||
|     content.room_version = RoomVersionId::Version6; |     content.room_version = RoomVersionId::Version6; | ||||||
| 
 | 
 | ||||||
|     // 1. The room create event
 |     // 1. The room create event
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomCreate, |             PduBuilder { | ||||||
|             content: serde_json::to_value(content).expect("event is valid, we just created it"), |                 event_type: EventType::RoomCreate, | ||||||
|             unsigned: None, |                 content: serde_json::to_value(content).expect("event is valid, we just created it"), | ||||||
|             state_key: Some("".to_owned()), |                 unsigned: None, | ||||||
|             redacts: None, |                 state_key: Some("".to_owned()), | ||||||
|         }, |                 redacts: None, | ||||||
|         &sender_id, |             }, | ||||||
|         &room_id, |             &sender_id, | ||||||
|         &db.globals, |             &room_id, | ||||||
|         &db.account_data, |             &db.globals, | ||||||
|     ).await?; |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // 2. Let the room creator join
 |     // 2. Let the room creator join
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomMember, |             PduBuilder { | ||||||
|             content: serde_json::to_value(member::MemberEventContent { |                 event_type: EventType::RoomMember, | ||||||
|                 membership: member::MembershipState::Join, |                 content: serde_json::to_value(member::MemberEventContent { | ||||||
|                 displayname: db.users.displayname(&sender_id)?, |                     membership: member::MembershipState::Join, | ||||||
|                 avatar_url: db.users.avatar_url(&sender_id)?, |                     displayname: db.users.displayname(&sender_id)?, | ||||||
|                 is_direct: Some(body.is_direct), |                     avatar_url: db.users.avatar_url(&sender_id)?, | ||||||
|                 third_party_invite: None, |                     is_direct: Some(body.is_direct), | ||||||
|             }) |                     third_party_invite: None, | ||||||
|             .expect("event is valid, we just created it"), |                 }) | ||||||
|             unsigned: None, |                 .expect("event is valid, we just created it"), | ||||||
|             state_key: Some(sender_id.to_string()), |                 unsigned: None, | ||||||
|             redacts: None, |                 state_key: Some(sender_id.to_string()), | ||||||
|         }, |                 redacts: None, | ||||||
|         &sender_id, |             }, | ||||||
|         &room_id, |             &sender_id, | ||||||
|         &db.globals, |             &room_id, | ||||||
|         &db.account_data, |             &db.globals, | ||||||
|     ).await?; |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // 3. Power levels
 |     // 3. Power levels
 | ||||||
|     let mut users = BTreeMap::new(); |     let mut users = BTreeMap::new(); | ||||||
|  | @ -117,19 +123,22 @@ pub async fn create_room_route( | ||||||
|         }) |         }) | ||||||
|         .expect("event is valid, we just created it") |         .expect("event is valid, we just created it") | ||||||
|     }; |     }; | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomPowerLevels, |             PduBuilder { | ||||||
|             content: power_levels_content, |                 event_type: EventType::RoomPowerLevels, | ||||||
|             unsigned: None, |                 content: power_levels_content, | ||||||
|             state_key: Some("".to_owned()), |                 unsigned: None, | ||||||
|             redacts: None, |                 state_key: Some("".to_owned()), | ||||||
|         }, |                 redacts: None, | ||||||
|         &sender_id, |             }, | ||||||
|         &room_id, |             &sender_id, | ||||||
|         &db.globals, |             &room_id, | ||||||
|         &db.account_data, |             &db.globals, | ||||||
|     ).await?; |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // 4. Events set by preset
 |     // 4. Events set by preset
 | ||||||
| 
 | 
 | ||||||
|  | @ -140,73 +149,84 @@ pub async fn create_room_route( | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     // 4.1 Join Rules
 |     // 4.1 Join Rules
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomJoinRules, |             PduBuilder { | ||||||
|             content: match preset { |                 event_type: EventType::RoomJoinRules, | ||||||
|                 create_room::RoomPreset::PublicChat => serde_json::to_value( |                 content: match preset { | ||||||
|                     join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public), |                     create_room::RoomPreset::PublicChat => serde_json::to_value( | ||||||
|                 ) |                         join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public), | ||||||
|                 .expect("event is valid, we just created it"), |                     ) | ||||||
|                 // according to spec "invite" is the default
 |                     .expect("event is valid, we just created it"), | ||||||
|                 _ => serde_json::to_value(join_rules::JoinRulesEventContent::new( |                     // according to spec "invite" is the default
 | ||||||
|                     join_rules::JoinRule::Invite, |                     _ => serde_json::to_value(join_rules::JoinRulesEventContent::new( | ||||||
|                 )) |                         join_rules::JoinRule::Invite, | ||||||
|                 .expect("event is valid, we just created it"), |                     )) | ||||||
|  |                     .expect("event is valid, we just created it"), | ||||||
|  |                 }, | ||||||
|  |                 unsigned: None, | ||||||
|  |                 state_key: Some("".to_owned()), | ||||||
|  |                 redacts: None, | ||||||
|             }, |             }, | ||||||
|             unsigned: None, |             &sender_id, | ||||||
|             state_key: Some("".to_owned()), |             &room_id, | ||||||
|             redacts: None, |             &db.globals, | ||||||
|         }, |             &db.sending, | ||||||
|         &sender_id, |             &db.account_data, | ||||||
|         &room_id, |         ) | ||||||
|         &db.globals, |         .await?; | ||||||
|         &db.account_data, |  | ||||||
|     ).await?; |  | ||||||
| 
 | 
 | ||||||
|     // 4.2 History Visibility
 |     // 4.2 History Visibility
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomHistoryVisibility, |             PduBuilder { | ||||||
|             content: serde_json::to_value(history_visibility::HistoryVisibilityEventContent::new( |                 event_type: EventType::RoomHistoryVisibility, | ||||||
|                 history_visibility::HistoryVisibility::Shared, |                 content: serde_json::to_value( | ||||||
|             )) |                     history_visibility::HistoryVisibilityEventContent::new( | ||||||
|             .expect("event is valid, we just created it"), |                         history_visibility::HistoryVisibility::Shared, | ||||||
|             unsigned: None, |                     ), | ||||||
|             state_key: Some("".to_owned()), |                 ) | ||||||
|             redacts: None, |                 .expect("event is valid, we just created it"), | ||||||
|         }, |                 unsigned: None, | ||||||
|         &sender_id, |                 state_key: Some("".to_owned()), | ||||||
|         &room_id, |                 redacts: None, | ||||||
|         &db.globals, |             }, | ||||||
|         &db.account_data, |             &sender_id, | ||||||
|     ).await?; |             &room_id, | ||||||
|  |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // 4.3 Guest Access
 |     // 4.3 Guest Access
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomGuestAccess, |             PduBuilder { | ||||||
|             content: match preset { |                 event_type: EventType::RoomGuestAccess, | ||||||
|                 create_room::RoomPreset::PublicChat => { |                 content: match preset { | ||||||
|                     serde_json::to_value(guest_access::GuestAccessEventContent::new( |                     create_room::RoomPreset::PublicChat => { | ||||||
|                         guest_access::GuestAccess::Forbidden, |                         serde_json::to_value(guest_access::GuestAccessEventContent::new( | ||||||
|  |                             guest_access::GuestAccess::Forbidden, | ||||||
|  |                         )) | ||||||
|  |                         .expect("event is valid, we just created it") | ||||||
|  |                     } | ||||||
|  |                     _ => serde_json::to_value(guest_access::GuestAccessEventContent::new( | ||||||
|  |                         guest_access::GuestAccess::CanJoin, | ||||||
|                     )) |                     )) | ||||||
|                     .expect("event is valid, we just created it") |                     .expect("event is valid, we just created it"), | ||||||
|                 } |                 }, | ||||||
|                 _ => serde_json::to_value(guest_access::GuestAccessEventContent::new( |                 unsigned: None, | ||||||
|                     guest_access::GuestAccess::CanJoin, |                 state_key: Some("".to_owned()), | ||||||
|                 )) |                 redacts: None, | ||||||
|                 .expect("event is valid, we just created it"), |  | ||||||
|             }, |             }, | ||||||
|             unsigned: None, |             &sender_id, | ||||||
|             state_key: Some("".to_owned()), |             &room_id, | ||||||
|             redacts: None, |             &db.globals, | ||||||
|         }, |             &db.sending, | ||||||
|         &sender_id, |             &db.account_data, | ||||||
|         &room_id, |         ) | ||||||
|         &db.globals, |         .await?; | ||||||
|         &db.account_data, |  | ||||||
|     ).await?; |  | ||||||
| 
 | 
 | ||||||
|     // 5. Events listed in initial_state
 |     // 5. Events listed in initial_state
 | ||||||
|     for event in &body.initial_state { |     for event in &body.initial_state { | ||||||
|  | @ -220,78 +240,90 @@ pub async fn create_room_route( | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             pdu_builder, |             .build_and_append_pdu( | ||||||
|             &sender_id, |                 pdu_builder, | ||||||
|             &room_id, |                 &sender_id, | ||||||
|             &db.globals, |                 &room_id, | ||||||
|             &db.account_data, |                 &db.globals, | ||||||
|         ).await?; |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // 6. Events implied by name and topic
 |     // 6. Events implied by name and topic
 | ||||||
|     if let Some(name) = &body.name { |     if let Some(name) = &body.name { | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type: EventType::RoomName, |                 PduBuilder { | ||||||
|                 content: serde_json::to_value( |                     event_type: EventType::RoomName, | ||||||
|                     name::NameEventContent::new(name.clone()).map_err(|_| { |                     content: serde_json::to_value( | ||||||
|                         Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.") |                         name::NameEventContent::new(name.clone()).map_err(|_| { | ||||||
|                     })?, |                             Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.") | ||||||
|                 ) |                         })?, | ||||||
|                 .expect("event is valid, we just created it"), |                     ) | ||||||
|                 unsigned: None, |                     .expect("event is valid, we just created it"), | ||||||
|                 state_key: Some("".to_owned()), |                     unsigned: None, | ||||||
|                 redacts: None, |                     state_key: Some("".to_owned()), | ||||||
|             }, |                     redacts: None, | ||||||
|             &sender_id, |                 }, | ||||||
|             &room_id, |                 &sender_id, | ||||||
|             &db.globals, |                 &room_id, | ||||||
|             &db.account_data, |                 &db.globals, | ||||||
|         ).await?; |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if let Some(topic) = &body.topic { |     if let Some(topic) = &body.topic { | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type: EventType::RoomTopic, |                 PduBuilder { | ||||||
|                 content: serde_json::to_value(topic::TopicEventContent { |                     event_type: EventType::RoomTopic, | ||||||
|                     topic: topic.clone(), |                     content: serde_json::to_value(topic::TopicEventContent { | ||||||
|                 }) |                         topic: topic.clone(), | ||||||
|                 .expect("event is valid, we just created it"), |                     }) | ||||||
|                 unsigned: None, |                     .expect("event is valid, we just created it"), | ||||||
|                 state_key: Some("".to_owned()), |                     unsigned: None, | ||||||
|                 redacts: None, |                     state_key: Some("".to_owned()), | ||||||
|             }, |                     redacts: None, | ||||||
|             &sender_id, |                 }, | ||||||
|             &room_id, |                 &sender_id, | ||||||
|             &db.globals, |                 &room_id, | ||||||
|             &db.account_data, |                 &db.globals, | ||||||
|         ).await?; |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // 7. Events implied by invite (and TODO: invite_3pid)
 |     // 7. Events implied by invite (and TODO: invite_3pid)
 | ||||||
|     for user in &body.invite { |     for user in &body.invite { | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type: EventType::RoomMember, |                 PduBuilder { | ||||||
|                 content: serde_json::to_value(member::MemberEventContent { |                     event_type: EventType::RoomMember, | ||||||
|                     membership: member::MembershipState::Invite, |                     content: serde_json::to_value(member::MemberEventContent { | ||||||
|                     displayname: db.users.displayname(&user)?, |                         membership: member::MembershipState::Invite, | ||||||
|                     avatar_url: db.users.avatar_url(&user)?, |                         displayname: db.users.displayname(&user)?, | ||||||
|                     is_direct: Some(body.is_direct), |                         avatar_url: db.users.avatar_url(&user)?, | ||||||
|                     third_party_invite: None, |                         is_direct: Some(body.is_direct), | ||||||
|                 }) |                         third_party_invite: None, | ||||||
|                 .expect("event is valid, we just created it"), |                     }) | ||||||
|                 unsigned: None, |                     .expect("event is valid, we just created it"), | ||||||
|                 state_key: Some(user.to_string()), |                     unsigned: None, | ||||||
|                 redacts: None, |                     state_key: Some(user.to_string()), | ||||||
|             }, |                     redacts: None, | ||||||
|             &sender_id, |                 }, | ||||||
|             &room_id, |                 &sender_id, | ||||||
|             &db.globals, |                 &room_id, | ||||||
|             &db.account_data, |                 &db.globals, | ||||||
|         ).await?; |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Homeserver specific stuff
 |     // Homeserver specific stuff
 | ||||||
|  | @ -363,23 +395,29 @@ pub async fn upgrade_room_route( | ||||||
| 
 | 
 | ||||||
|     // Send a m.room.tombstone event to the old room to indicate that it is not intended to be used any further
 |     // Send a m.room.tombstone event to the old room to indicate that it is not intended to be used any further
 | ||||||
|     // Fail if the sender does not have the required permissions
 |     // Fail if the sender does not have the required permissions
 | ||||||
|     let tombstone_event_id = db.rooms.build_and_append_pdu( |     let tombstone_event_id = db | ||||||
|         PduBuilder { |         .rooms | ||||||
|             event_type: EventType::RoomTombstone, |         .build_and_append_pdu( | ||||||
|             content: serde_json::to_value(ruma::events::room::tombstone::TombstoneEventContent { |             PduBuilder { | ||||||
|                 body: "This room has been replaced".to_string(), |                 event_type: EventType::RoomTombstone, | ||||||
|                 replacement_room: replacement_room.clone(), |                 content: serde_json::to_value( | ||||||
|             }) |                     ruma::events::room::tombstone::TombstoneEventContent { | ||||||
|             .expect("event is valid, we just created it"), |                         body: "This room has been replaced".to_string(), | ||||||
|             unsigned: None, |                         replacement_room: replacement_room.clone(), | ||||||
|             state_key: Some("".to_owned()), |                     }, | ||||||
|             redacts: None, |                 ) | ||||||
|         }, |                 .expect("event is valid, we just created it"), | ||||||
|         sender_id, |                 unsigned: None, | ||||||
|         &body.room_id, |                 state_key: Some("".to_owned()), | ||||||
|         &db.globals, |                 redacts: None, | ||||||
|         &db.account_data, |             }, | ||||||
|     ).await?; |             sender_id, | ||||||
|  |             &body.room_id, | ||||||
|  |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // Get the old room federations status
 |     // Get the old room federations status
 | ||||||
|     let federate = serde_json::from_value::<Raw<ruma::events::room::create::CreateEventContent>>( |     let federate = serde_json::from_value::<Raw<ruma::events::room::create::CreateEventContent>>( | ||||||
|  | @ -406,42 +444,48 @@ pub async fn upgrade_room_route( | ||||||
|     create_event_content.room_version = new_version; |     create_event_content.room_version = new_version; | ||||||
|     create_event_content.predecessor = predecessor; |     create_event_content.predecessor = predecessor; | ||||||
| 
 | 
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomCreate, |             PduBuilder { | ||||||
|             content: serde_json::to_value(create_event_content) |                 event_type: EventType::RoomCreate, | ||||||
|                 .expect("event is valid, we just created it"), |                 content: serde_json::to_value(create_event_content) | ||||||
|             unsigned: None, |                     .expect("event is valid, we just created it"), | ||||||
|             state_key: Some("".to_owned()), |                 unsigned: None, | ||||||
|             redacts: None, |                 state_key: Some("".to_owned()), | ||||||
|         }, |                 redacts: None, | ||||||
|         sender_id, |             }, | ||||||
|         &replacement_room, |             sender_id, | ||||||
|         &db.globals, |             &replacement_room, | ||||||
|         &db.account_data, |             &db.globals, | ||||||
|     ).await?; |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // Join the new room
 |     // Join the new room
 | ||||||
|     db.rooms.build_and_append_pdu( |     db.rooms | ||||||
|         PduBuilder { |         .build_and_append_pdu( | ||||||
|             event_type: EventType::RoomMember, |             PduBuilder { | ||||||
|             content: serde_json::to_value(member::MemberEventContent { |                 event_type: EventType::RoomMember, | ||||||
|                 membership: member::MembershipState::Join, |                 content: serde_json::to_value(member::MemberEventContent { | ||||||
|                 displayname: db.users.displayname(&sender_id)?, |                     membership: member::MembershipState::Join, | ||||||
|                 avatar_url: db.users.avatar_url(&sender_id)?, |                     displayname: db.users.displayname(&sender_id)?, | ||||||
|                 is_direct: None, |                     avatar_url: db.users.avatar_url(&sender_id)?, | ||||||
|                 third_party_invite: None, |                     is_direct: None, | ||||||
|             }) |                     third_party_invite: None, | ||||||
|             .expect("event is valid, we just created it"), |                 }) | ||||||
|             unsigned: None, |                 .expect("event is valid, we just created it"), | ||||||
|             state_key: Some(sender_id.to_string()), |                 unsigned: None, | ||||||
|             redacts: None, |                 state_key: Some(sender_id.to_string()), | ||||||
|         }, |                 redacts: None, | ||||||
|         sender_id, |             }, | ||||||
|         &replacement_room, |             sender_id, | ||||||
|         &db.globals, |             &replacement_room, | ||||||
|         &db.account_data, |             &db.globals, | ||||||
|     ).await?; |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     // Recommended transferable state events list from the specs
 |     // Recommended transferable state events list from the specs
 | ||||||
|     let transferable_state_events = vec![ |     let transferable_state_events = vec![ | ||||||
|  | @ -463,19 +507,22 @@ pub async fn upgrade_room_route( | ||||||
|             None => continue, // Skipping missing events.
 |             None => continue, // Skipping missing events.
 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         db.rooms.build_and_append_pdu( |         db.rooms | ||||||
|             PduBuilder { |             .build_and_append_pdu( | ||||||
|                 event_type, |                 PduBuilder { | ||||||
|                 content: event_content, |                     event_type, | ||||||
|                 unsigned: None, |                     content: event_content, | ||||||
|                 state_key: Some("".to_owned()), |                     unsigned: None, | ||||||
|                 redacts: None, |                     state_key: Some("".to_owned()), | ||||||
|             }, |                     redacts: None, | ||||||
|             sender_id, |                 }, | ||||||
|             &replacement_room, |                 sender_id, | ||||||
|             &db.globals, |                 &replacement_room, | ||||||
|             &db.account_data, |                 &db.globals, | ||||||
|         ).await?; |                 &db.sending, | ||||||
|  |                 &db.account_data, | ||||||
|  |             ) | ||||||
|  |             .await?; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Moves any local aliases to the new room
 |     // Moves any local aliases to the new room
 | ||||||
|  | @ -505,7 +552,8 @@ pub async fn upgrade_room_route( | ||||||
|     power_levels_event_content.invite = new_level; |     power_levels_event_content.invite = new_level; | ||||||
| 
 | 
 | ||||||
|     // Modify the power levels in the old room to prevent sending of events and inviting new users
 |     // Modify the power levels in the old room to prevent sending of events and inviting new users
 | ||||||
|     let _ = db.rooms |     let _ = db | ||||||
|  |         .rooms | ||||||
|         .build_and_append_pdu( |         .build_and_append_pdu( | ||||||
|             PduBuilder { |             PduBuilder { | ||||||
|                 event_type: EventType::RoomPowerLevels, |                 event_type: EventType::RoomPowerLevels, | ||||||
|  | @ -518,8 +566,10 @@ pub async fn upgrade_room_route( | ||||||
|             sender_id, |             sender_id, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             &db.globals, |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|             &db.account_data, |             &db.account_data, | ||||||
|         ).await; |         ) | ||||||
|  |         .await; | ||||||
| 
 | 
 | ||||||
|     // Return the replacement room id
 |     // Return the replacement room id
 | ||||||
|     Ok(upgrade_room::Response { replacement_room }.into()) |     Ok(upgrade_room::Response { replacement_room }.into()) | ||||||
|  |  | ||||||
|  | @ -33,17 +33,18 @@ pub async fn send_state_event_for_key_route( | ||||||
|     ) |     ) | ||||||
|     .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?; |     .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?; | ||||||
| 
 | 
 | ||||||
|     Ok( |     Ok(send_state_event_for_key::Response::new( | ||||||
|         send_state_event_for_key::Response::new(send_state_event_for_key_helper( |         send_state_event_for_key_helper( | ||||||
|             &db, |             &db, | ||||||
|             sender_id, |             sender_id, | ||||||
|             &body.content, |             &body.content, | ||||||
|             content, |             content, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             Some(body.state_key.to_owned()), |             Some(body.state_key.to_owned()), | ||||||
|         ).await?) |         ) | ||||||
|         .into(), |         .await?, | ||||||
|     ) |     ) | ||||||
|  |     .into()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[cfg_attr(
 | #[cfg_attr(
 | ||||||
|  | @ -70,8 +71,8 @@ pub async fn send_state_event_for_empty_key_route( | ||||||
|     ) |     ) | ||||||
|     .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?; |     .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?; | ||||||
| 
 | 
 | ||||||
|     Ok( |     Ok(send_state_event_for_empty_key::Response::new( | ||||||
|         send_state_event_for_empty_key::Response::new(send_state_event_for_key_helper( |         send_state_event_for_key_helper( | ||||||
|             &db, |             &db, | ||||||
|             sender_id |             sender_id | ||||||
|                 .as_ref() |                 .as_ref() | ||||||
|  | @ -80,9 +81,10 @@ pub async fn send_state_event_for_empty_key_route( | ||||||
|             json, |             json, | ||||||
|             &body.room_id, |             &body.room_id, | ||||||
|             Some("".into()), |             Some("".into()), | ||||||
|         ).await?) |         ) | ||||||
|         .into(), |         .await?, | ||||||
|     ) |     ) | ||||||
|  |     .into()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[cfg_attr(
 | #[cfg_attr(
 | ||||||
|  | @ -211,19 +213,23 @@ pub async fn send_state_event_for_key_helper( | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let event_id = db.rooms.build_and_append_pdu( |     let event_id = db | ||||||
|         PduBuilder { |         .rooms | ||||||
|             event_type: content.event_type().into(), |         .build_and_append_pdu( | ||||||
|             content: json, |             PduBuilder { | ||||||
|             unsigned: None, |                 event_type: content.event_type().into(), | ||||||
|             state_key, |                 content: json, | ||||||
|             redacts: None, |                 unsigned: None, | ||||||
|         }, |                 state_key, | ||||||
|         &sender_id, |                 redacts: None, | ||||||
|         &room_id, |             }, | ||||||
|         &db.globals, |             &sender_id, | ||||||
|         &db.account_data, |             &room_id, | ||||||
|     ).await?; |             &db.globals, | ||||||
|  |             &db.sending, | ||||||
|  |             &db.account_data, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
| 
 | 
 | ||||||
|     Ok(event_id) |     Ok(event_id) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ pub mod globals; | ||||||
| pub mod key_backups; | pub mod key_backups; | ||||||
| pub mod media; | pub mod media; | ||||||
| pub mod rooms; | pub mod rooms; | ||||||
|  | pub mod sending; | ||||||
| pub mod transaction_ids; | pub mod transaction_ids; | ||||||
| pub mod uiaa; | pub mod uiaa; | ||||||
| pub mod users; | pub mod users; | ||||||
|  | @ -25,6 +26,7 @@ pub struct Database { | ||||||
|     pub media: media::Media, |     pub media: media::Media, | ||||||
|     pub key_backups: key_backups::KeyBackups, |     pub key_backups: key_backups::KeyBackups, | ||||||
|     pub transaction_ids: transaction_ids::TransactionIds, |     pub transaction_ids: transaction_ids::TransactionIds, | ||||||
|  |     pub sending: sending::Sending, | ||||||
|     pub _db: sled::Db, |     pub _db: sled::Db, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -135,6 +137,9 @@ impl Database { | ||||||
|             transaction_ids: transaction_ids::TransactionIds { |             transaction_ids: transaction_ids::TransactionIds { | ||||||
|                 userdevicetxnid_response: db.open_tree("userdevicetxnid_response")?, |                 userdevicetxnid_response: db.open_tree("userdevicetxnid_response")?, | ||||||
|             }, |             }, | ||||||
|  |             sending: sending::Sending { | ||||||
|  |                 serverpduids: db.open_tree("serverpduids")?, | ||||||
|  |             }, | ||||||
|             _db: db, |             _db: db, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,12 +1,13 @@ | ||||||
| use crate::{utils, Error, Result}; | use crate::{utils, Error, Result}; | ||||||
| use ruma::ServerName; | use ruma::ServerName; | ||||||
| use std::convert::TryInto; | use std::{convert::TryInto, sync::Arc}; | ||||||
| 
 | 
 | ||||||
| pub const COUNTER: &str = "c"; | pub const COUNTER: &str = "c"; | ||||||
| 
 | 
 | ||||||
|  | #[derive(Clone)] | ||||||
| pub struct Globals { | pub struct Globals { | ||||||
|     pub(super) globals: sled::Tree, |     pub(super) globals: sled::Tree, | ||||||
|     keypair: ruma::signatures::Ed25519KeyPair, |     keypair: Arc<ruma::signatures::Ed25519KeyPair>, | ||||||
|     reqwest_client: reqwest::Client, |     reqwest_client: reqwest::Client, | ||||||
|     server_name: Box<ServerName>, |     server_name: Box<ServerName>, | ||||||
|     max_request_size: u32, |     max_request_size: u32, | ||||||
|  | @ -16,13 +17,15 @@ pub struct Globals { | ||||||
| 
 | 
 | ||||||
| impl Globals { | impl Globals { | ||||||
|     pub fn load(globals: sled::Tree, config: &rocket::Config) -> Result<Self> { |     pub fn load(globals: sled::Tree, config: &rocket::Config) -> Result<Self> { | ||||||
|         let keypair = ruma::signatures::Ed25519KeyPair::new( |         let keypair = Arc::new( | ||||||
|             &*globals |             ruma::signatures::Ed25519KeyPair::new( | ||||||
|                 .update_and_fetch("keypair", utils::generate_keypair)? |                 &*globals | ||||||
|                 .expect("utils::generate_keypair always returns Some"), |                     .update_and_fetch("keypair", utils::generate_keypair)? | ||||||
|             "key1".to_owned(), |                     .expect("utils::generate_keypair always returns Some"), | ||||||
|         ) |                 "key1".to_owned(), | ||||||
|         .map_err(|_| Error::bad_database("Private or public keys are invalid."))?; |             ) | ||||||
|  |             .map_err(|_| Error::bad_database("Private or public keys are invalid."))?, | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         Ok(Self { |         Ok(Self { | ||||||
|             globals, |             globals, | ||||||
|  |  | ||||||
|  | @ -1,14 +1,12 @@ | ||||||
| mod edus; | mod edus; | ||||||
| 
 | 
 | ||||||
| pub use edus::RoomEdus; | pub use edus::RoomEdus; | ||||||
| use rocket::futures; |  | ||||||
| 
 | 
 | ||||||
| use crate::{pdu::PduBuilder, server_server, utils, Error, PduEvent, Result}; | use crate::{pdu::PduBuilder, utils, Error, PduEvent, Result}; | ||||||
| use log::{error, warn}; | use log::error; | ||||||
| use ring::digest; | use ring::digest; | ||||||
| use ruma::{ | use ruma::{ | ||||||
|     api::client::error::ErrorKind, |     api::client::error::ErrorKind, | ||||||
|     api::federation, |  | ||||||
|     events::{ |     events::{ | ||||||
|         ignored_user_list, |         ignored_user_list, | ||||||
|         room::{ |         room::{ | ||||||
|  | @ -27,7 +25,6 @@ use std::{ | ||||||
|     convert::{TryFrom, TryInto}, |     convert::{TryFrom, TryInto}, | ||||||
|     mem, |     mem, | ||||||
|     sync::Arc, |     sync::Arc, | ||||||
|     time::SystemTime, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// The unique identifier of each state group.
 | /// The unique identifier of each state group.
 | ||||||
|  | @ -36,6 +33,7 @@ use std::{ | ||||||
| /// hashing the entire state.
 | /// hashing the entire state.
 | ||||||
| pub type StateHashId = Vec<u8>; | pub type StateHashId = Vec<u8>; | ||||||
| 
 | 
 | ||||||
|  | #[derive(Clone)] | ||||||
| pub struct Rooms { | pub struct Rooms { | ||||||
|     pub edus: edus::RoomEdus, |     pub edus: edus::RoomEdus, | ||||||
|     pub(super) pduid_pdu: sled::Tree, // PduId = RoomId + Count
 |     pub(super) pduid_pdu: sled::Tree, // PduId = RoomId + Count
 | ||||||
|  | @ -415,6 +413,16 @@ impl Rooms { | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// Returns the pdu.
 | ||||||
|  |     pub fn get_pdu_json_from_id(&self, pdu_id: &IVec) -> Result<Option<serde_json::Value>> { | ||||||
|  |         self.pduid_pdu.get(pdu_id)?.map_or(Ok(None), |pdu| { | ||||||
|  |             Ok(Some( | ||||||
|  |                 serde_json::from_slice(&pdu) | ||||||
|  |                     .map_err(|_| Error::bad_database("Invalid PDU in db."))?, | ||||||
|  |             )) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Removes a pdu and creates a new one with the same id.
 |     /// Removes a pdu and creates a new one with the same id.
 | ||||||
|     fn replace_pdu(&self, pdu_id: &IVec, pdu: &PduEvent) -> Result<()> { |     fn replace_pdu(&self, pdu_id: &IVec, pdu: &PduEvent) -> Result<()> { | ||||||
|         if self.pduid_pdu.get(&pdu_id)?.is_some() { |         if self.pduid_pdu.get(&pdu_id)?.is_some() { | ||||||
|  | @ -613,6 +621,7 @@ impl Rooms { | ||||||
|         sender: &UserId, |         sender: &UserId, | ||||||
|         room_id: &RoomId, |         room_id: &RoomId, | ||||||
|         globals: &super::globals::Globals, |         globals: &super::globals::Globals, | ||||||
|  |         sending: &super::sending::Sending, | ||||||
|         account_data: &super::account_data::AccountData, |         account_data: &super::account_data::AccountData, | ||||||
|     ) -> Result<EventId> { |     ) -> Result<EventId> { | ||||||
|         let PduBuilder { |         let PduBuilder { | ||||||
|  | @ -829,39 +838,12 @@ impl Rooms { | ||||||
|             self.append_to_state(&pdu_id, &pdu)?; |             self.append_to_state(&pdu_id, &pdu)?; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pdu_json |         for server in self | ||||||
|             .as_object_mut() |             .room_servers(room_id) | ||||||
|             .expect("json is object") |             .filter_map(|r| r.ok()) | ||||||
|             .remove("event_id"); |             .filter(|server| &**server != globals.server_name()) | ||||||
| 
 |         { | ||||||
|         let raw_json = |             sending.send_pdu(server, &pdu_id)?; | ||||||
|             serde_json::from_value::<Raw<_>>(pdu_json).expect("Raw::from_value always works"); |  | ||||||
| 
 |  | ||||||
|         let pdus = &[raw_json]; |  | ||||||
|         let transaction_id = utils::random_string(16); |  | ||||||
| 
 |  | ||||||
|         for result in futures::future::join_all( |  | ||||||
|             self.room_servers(room_id) |  | ||||||
|                 .filter_map(|r| r.ok()) |  | ||||||
|                 .filter(|server| &**server != globals.server_name()) |  | ||||||
|                 .map(|server| { |  | ||||||
|                     server_server::send_request( |  | ||||||
|                         &globals, |  | ||||||
|                         server, |  | ||||||
|                         federation::transactions::send_transaction_message::v1::Request { |  | ||||||
|                             origin: globals.server_name(), |  | ||||||
|                             pdus, |  | ||||||
|                             edus: &[], |  | ||||||
|                             origin_server_ts: SystemTime::now(), |  | ||||||
|                             transaction_id: &transaction_id, |  | ||||||
|                         }, |  | ||||||
|                     ) |  | ||||||
|                 }), |  | ||||||
|         ) |  | ||||||
|         .await { |  | ||||||
|             if let Err(e) = result { |  | ||||||
|                 warn!("{}", e); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Ok(pdu.event_id) |         Ok(pdu.event_id) | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ use std::{ | ||||||
|     convert::{TryFrom, TryInto}, |     convert::{TryFrom, TryInto}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | #[derive(Clone)] | ||||||
| pub struct RoomEdus { | pub struct RoomEdus { | ||||||
|     pub(in super::super) readreceiptid_readreceipt: sled::Tree, // ReadReceiptId = RoomId + Count + UserId
 |     pub(in super::super) readreceiptid_readreceipt: sled::Tree, // ReadReceiptId = RoomId + Count + UserId
 | ||||||
|     pub(in super::super) roomuserid_privateread: sled::Tree, // RoomUserId = Room + User, PrivateRead = Count
 |     pub(in super::super) roomuserid_privateread: sled::Tree, // RoomUserId = Room + User, PrivateRead = Count
 | ||||||
|  |  | ||||||
							
								
								
									
										83
									
								
								src/database/sending.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/database/sending.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,83 @@ | ||||||
|  | use std::{convert::TryFrom, time::SystemTime}; | ||||||
|  | 
 | ||||||
|  | use crate::{server_server, utils, Error, Result}; | ||||||
|  | use rocket::futures::stream::{FuturesUnordered, StreamExt}; | ||||||
|  | use ruma::{api::federation, Raw, ServerName}; | ||||||
|  | use tokio::select; | ||||||
|  | 
 | ||||||
|  | pub struct Sending { | ||||||
|  |     /// The state for a given state hash.
 | ||||||
|  |     pub(super) serverpduids: sled::Tree, // ServerPduId = ServerName + PduId
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Sending { | ||||||
|  |     pub fn start_handler(&self, globals: &super::globals::Globals, rooms: &super::rooms::Rooms) { | ||||||
|  |         let serverpduids = self.serverpduids.clone(); | ||||||
|  |         let rooms = rooms.clone(); | ||||||
|  |         let globals = globals.clone(); | ||||||
|  | 
 | ||||||
|  |         tokio::spawn(async move { | ||||||
|  |             let mut futures = FuturesUnordered::new(); | ||||||
|  |             let mut subscriber = serverpduids.watch_prefix(b""); | ||||||
|  |             loop { | ||||||
|  |                 select! { | ||||||
|  |                     Some(_) = futures.next() => {}, | ||||||
|  |                     Some(event) = &mut subscriber => { | ||||||
|  |                         let serverpduid = if let sled::Event::Insert {key, ..} = event { | ||||||
|  |                             key | ||||||
|  |                         } else | ||||||
|  |                         { return Err::<(), Error>(Error::bad_database("")); }; | ||||||
|  |                         let mut parts = serverpduid.splitn(2, |&b| b == 0xff); | ||||||
|  |                         let server = Box::<ServerName>::try_from( | ||||||
|  |                             utils::string_from_bytes(parts.next().expect("splitn will always return 1 or more elements")) | ||||||
|  |                                 .map_err(|_| Error::bad_database("ServerName in serverpduid bytes are invalid."))? | ||||||
|  |                             ).map_err(|_| Error::bad_database("ServerName in serverpduid is invalid."))?; | ||||||
|  | 
 | ||||||
|  |                         let pdu_id = parts.next().ok_or_else(|| Error::bad_database("Invalid serverpduid in db."))?; | ||||||
|  |                         let mut pdu_json = rooms.get_pdu_json_from_id(&pdu_id.into())?.ok_or_else(|| Error::bad_database("Event in serverpduids not found in db."))?; | ||||||
|  | 
 | ||||||
|  |                         pdu_json | ||||||
|  |                             .as_object_mut() | ||||||
|  |                             .expect("json is object") | ||||||
|  |                             .remove("event_id"); | ||||||
|  | 
 | ||||||
|  |                         let raw_json = | ||||||
|  |                             serde_json::from_value::<Raw<_>>(pdu_json).expect("Raw::from_value always works"); | ||||||
|  | 
 | ||||||
|  |                         let globals = &globals; | ||||||
|  | 
 | ||||||
|  |                         futures.push( | ||||||
|  |                             async move { | ||||||
|  |                                 let pdus = vec![raw_json]; | ||||||
|  |                                 let transaction_id = utils::random_string(16); | ||||||
|  | 
 | ||||||
|  |                                 server_server::send_request( | ||||||
|  |                                     &globals, | ||||||
|  |                                     server, | ||||||
|  |                                     federation::transactions::send_transaction_message::v1::Request { | ||||||
|  |                                         origin: globals.server_name(), | ||||||
|  |                                         pdus: &pdus, | ||||||
|  |                                         edus: &[], | ||||||
|  |                                         origin_server_ts: SystemTime::now(), | ||||||
|  |                                         transaction_id: &transaction_id, | ||||||
|  |                                     }, | ||||||
|  |                                 ).await | ||||||
|  |                             } | ||||||
|  |                         ); | ||||||
|  |                     }, | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     /* | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     pub fn send_pdu(&self, server: Box<ServerName>, pdu_id: &[u8]) -> Result<()> { | ||||||
|  |         let mut key = server.as_bytes().to_vec(); | ||||||
|  |         key.push(0xff); | ||||||
|  |         key.extend_from_slice(pdu_id); | ||||||
|  |         self.serverpduids.insert(key, b"")?; | ||||||
|  | 
 | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -130,6 +130,8 @@ fn setup_rocket() -> rocket::Rocket { | ||||||
|         .attach(AdHoc::on_attach("Config", |mut rocket| async { |         .attach(AdHoc::on_attach("Config", |mut rocket| async { | ||||||
|             let data = Database::load_or_create(rocket.config().await).expect("valid config"); |             let data = Database::load_or_create(rocket.config().await).expect("valid config"); | ||||||
| 
 | 
 | ||||||
|  |             data.sending.start_handler(&data.globals, &data.rooms); | ||||||
|  | 
 | ||||||
|             Ok(rocket.manage(data)) |             Ok(rocket.manage(data)) | ||||||
|         })) |         })) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,12 +1,13 @@ | ||||||
| use crate::{Error, Result}; | use crate::{Error, Result}; | ||||||
| use js_int::UInt; | use js_int::UInt; | ||||||
| use ruma::{ | use ruma::{ | ||||||
|  |     events::pdu::PduStub, | ||||||
|     events::{ |     events::{ | ||||||
|         pdu::EventHash, room::member::MemberEventContent, AnyEvent, AnyRoomEvent, AnyStateEvent, |         pdu::EventHash, room::member::MemberEventContent, AnyEvent, AnyRoomEvent, AnyStateEvent, | ||||||
|         AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventType, StateEvent, |         AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventType, StateEvent, | ||||||
|     }, |     }, | ||||||
|     EventId, Raw, RoomId, ServerKeyId, ServerName, UserId, |     EventId, Raw, RoomId, ServerKeyId, ServerName, UserId, | ||||||
| events::pdu::PduStub}; | }; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use serde_json::json; | use serde_json::json; | ||||||
| use std::{collections::BTreeMap, convert::TryInto, sync::Arc, time::UNIX_EPOCH}; | use std::{collections::BTreeMap, convert::TryInto, sync::Arc, time::UNIX_EPOCH}; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue