feat: allow overriding the "most recent event" when forcing a state download (#853)
Some checks failed
Documentation / Build and Deploy Documentation (push) Failing after 28s
Release Docker Image / define-variables (push) Failing after 2s
Release Docker Image / build-image (linux/amd64, linux-amd64) (push) Has been skipped
Release Docker Image / build-image (linux/arm64, linux-arm64) (push) Has been skipped
Release Docker Image / merge (push) Has been skipped
Rust Checks / Format (push) Failing after 1s
Rust Checks / Clippy (push) Failing after 11s
Rust Checks / Cargo Test (push) Failing after 10s

Add option to select which event to set the state at to, for the force-set-room-state admin command.

This allows us to work around issues where the latest PDU is one that remote servers don't know about (i.e. failed federation for whatever reason)

Closes #852

Reviewed-on: https://forgejo.ellis.link/continuwuation/continuwuity/pulls/853
Reviewed-by: Jade Ellis <jade@ellis.link>
Co-authored-by: nex <nex@noreply.forgejo.ellis.link>
Co-committed-by: nex <nex@noreply.forgejo.ellis.link>
This commit is contained in:
nex 2025-06-19 21:27:50 +00:00 committed by Jade Ellis
parent d6fd30393c
commit e508b1197f
2 changed files with 26 additions and 14 deletions

View file

@ -239,10 +239,11 @@ pub(super) async fn get_remote_pdu(
}) })
.await .await
{ {
| Err(e) => | Err(e) => {
return Err!( return Err!(
"Remote server did not have PDU or failed sending request to remote server: {e}" "Remote server did not have PDU or failed sending request to remote server: {e}"
), );
},
| Ok(response) => { | Ok(response) => {
let json: CanonicalJsonObject = let json: CanonicalJsonObject =
serde_json::from_str(response.pdu.get()).map_err(|e| { serde_json::from_str(response.pdu.get()).map_err(|e| {
@ -384,8 +385,9 @@ pub(super) async fn change_log_level(&self, filter: Option<String>, reset: bool)
.reload .reload
.reload(&old_filter_layer, Some(handles)) .reload(&old_filter_layer, Some(handles))
{ {
| Err(e) => | Err(e) => {
return Err!("Failed to modify and reload the global tracing log level: {e}"), return Err!("Failed to modify and reload the global tracing log level: {e}");
},
| Ok(()) => { | Ok(()) => {
let value = &self.services.server.config.log; let value = &self.services.server.config.log;
let out = format!("Successfully changed log level back to config value {value}"); let out = format!("Successfully changed log level back to config value {value}");
@ -408,8 +410,9 @@ pub(super) async fn change_log_level(&self, filter: Option<String>, reset: bool)
.reload(&new_filter_layer, Some(handles)) .reload(&new_filter_layer, Some(handles))
{ {
| Ok(()) => return self.write_str("Successfully changed log level").await, | Ok(()) => return self.write_str("Successfully changed log level").await,
| Err(e) => | Err(e) => {
return Err!("Failed to modify and reload the global tracing log level: {e}"), return Err!("Failed to modify and reload the global tracing log level: {e}");
},
} }
} }
@ -529,6 +532,7 @@ pub(super) async fn force_set_room_state_from_server(
&self, &self,
room_id: OwnedRoomId, room_id: OwnedRoomId,
server_name: OwnedServerName, server_name: OwnedServerName,
at_event: Option<OwnedEventId>,
) -> Result { ) -> Result {
if !self if !self
.services .services
@ -540,13 +544,18 @@ pub(super) async fn force_set_room_state_from_server(
return Err!("We are not participating in the room / we don't know about the room ID."); return Err!("We are not participating in the room / we don't know about the room ID.");
} }
let first_pdu = self let at_event_id = match at_event {
.services | Some(event_id) => event_id,
.rooms | None => self
.timeline .services
.latest_pdu_in_room(&room_id) .rooms
.await .timeline
.map_err(|_| err!(Database("Failed to find the latest PDU in database")))?; .latest_pdu_in_room(&room_id)
.await
.map_err(|_| err!(Database("Failed to find the latest PDU in database")))?
.event_id
.clone(),
};
let room_version = self.services.rooms.state.get_room_version(&room_id).await?; let room_version = self.services.rooms.state.get_room_version(&room_id).await?;
@ -557,7 +566,7 @@ pub(super) async fn force_set_room_state_from_server(
.sending .sending
.send_federation_request(&server_name, get_room_state::v1::Request { .send_federation_request(&server_name, get_room_state::v1::Request {
room_id: room_id.clone(), room_id: room_id.clone(),
event_id: first_pdu.event_id.clone(), event_id: at_event_id,
}) })
.await?; .await?;

View file

@ -177,6 +177,9 @@ pub(super) enum DebugCommand {
room_id: OwnedRoomId, room_id: OwnedRoomId,
/// The server we will use to query the room state for /// The server we will use to query the room state for
server_name: OwnedServerName, server_name: OwnedServerName,
/// The event ID of the latest known PDU in the room. Will be found
/// automatically if not provided.
event_id: Option<OwnedEventId>,
}, },
/// - Runs a server name through conduwuit's true destination resolution /// - Runs a server name through conduwuit's true destination resolution