diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index ce304a1e8..012764785 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -7,10 +7,7 @@ use std::{ use conduwuit::{ Err, Result, debug_error, err, info, - matrix::{ - Event, - pdu::{PduEvent, PduId, RawPduId}, - }, + matrix::{Event, pdu::PduEvent}, trace, utils, utils::{ stream::{IterStream, ReadyExt}, @@ -28,10 +25,7 @@ use ruma::{ CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName, RoomId, RoomVersionId, UInt, api::federation::event::get_room_state, }; -use service::rooms::{ - short::{ShortEventId, ShortRoomId}, - state_compressor::HashSetCompressStateEvent, -}; +use service::rooms::state_compressor::HashSetCompressStateEvent; use tracing_subscriber::EnvFilter; use crate::PAGE_SIZE; @@ -300,79 +294,6 @@ impl crate::Context<'_> { .await } - pub(super) async fn get_pdu(&self, event_id: OwnedEventId) -> Result { - let mut outlier = false; - let mut pdu_json = self - .services - .rooms - .timeline - .get_non_outlier_pdu_json(&event_id) - .await; - - if pdu_json.is_err() { - outlier = true; - pdu_json = self.services.rooms.timeline.get_pdu_json(&event_id).await; - } - let rejected = self - .services - .rooms - .pdu_metadata - .is_event_rejected(&event_id) - .await; - let soft_failed = self - .services - .rooms - .pdu_metadata - .is_event_soft_failed(&event_id) - .await; - - match pdu_json { - | Err(_) => return Err!("PDU not found locally."), - | Ok(json) => { - let text = serde_json::to_string_pretty(&json)?; - let msg = if rejected { - "Rejected PDU:" - } else if soft_failed { - "Soft-failed PDU:" - } else if outlier { - "Outlier PDU:" - } else { - "PDU:" - }; - write!(self, "{msg}\n```json\n{text}\n```") - }, - } - .await - } - - pub(super) async fn get_short_pdu( - &self, - shortroomid: ShortRoomId, - shorteventid: ShortEventId, - ) -> Result { - let pdu_id: RawPduId = PduId { - shortroomid, - shorteventid: shorteventid.into(), - } - .into(); - - let pdu_json = self - .services - .rooms - .timeline - .get_pdu_json_from_id(&pdu_id) - .await; - - match pdu_json { - | Err(_) => return Err!("PDU not found locally."), - | Ok(json) => { - let json_text = serde_json::to_string_pretty(&json)?; - write!(self, "```json\n{json_text}\n```") - }, - } - .await - } - pub(super) async fn get_remote_pdu_list( &self, server: OwnedServerName, @@ -624,62 +545,6 @@ impl crate::Context<'_> { self.write_str(msg).await } - #[tracing::instrument(skip(self), level = "info")] - pub(super) async fn first_pdu_in_room(&self, room_id: OwnedRoomId) -> Result { - self.bail_restricted()?; - - if !self - .services - .rooms - .state_cache - .server_in_room(&self.services.server.name, &room_id) - .await - { - return Err!( - "We are not participating in the room / we don't know about the room ID.", - ); - } - - let first_pdu = self - .services - .rooms - .timeline - .first_pdu_in_room(&room_id) - .await - .map_err(|_| err!(Database("Failed to find the first PDU in database")))?; - - let out = format!("{first_pdu:?}"); - self.write_str(&out).await - } - - #[tracing::instrument(skip(self), level = "info")] - pub(super) async fn latest_pdu_in_room(&self, room_id: OwnedRoomId) -> Result { - self.bail_restricted()?; - - if !self - .services - .rooms - .state_cache - .server_in_room(&self.services.server.name, &room_id) - .await - { - return Err!( - "We are not participating in the room / we don't know about the room ID." - ); - } - - let latest_pdu = self - .services - .rooms - .timeline - .latest_pdu_in_room(&room_id) - .await - .map_err(|_| err!(Database("Failed to find the latest PDU in database")))?; - - let out = format!("{latest_pdu:?}"); - self.write_str(&out).await - } - #[tracing::instrument(skip(self), level = "info")] pub(super) async fn force_set_room_state_from_server( &self, diff --git a/src/admin/debug/mod.rs b/src/admin/debug/mod.rs index 6b49ae980..bc20d07aa 100644 --- a/src/admin/debug/mod.rs +++ b/src/admin/debug/mod.rs @@ -4,7 +4,6 @@ pub(crate) mod tester; use clap::Subcommand; use conduwuit::Result; use ruma::{OwnedEventId, OwnedRoomId, OwnedServerName}; -use service::rooms::short::{ShortEventId, ShortRoomId}; use self::tester::TesterCommand; use crate::admin_command_dispatch; @@ -41,21 +40,6 @@ pub enum DebugCommand { /// the command. ParsePdu, - /// Retrieve and print a PDU by EventID from the Continuwuity database - GetPdu { - /// An event ID (a $ followed by the base64 reference hash) - event_id: OwnedEventId, - }, - - /// Retrieve and print a PDU by PduId from the Continuwuity database - GetShortPdu { - /// Shortroomid integer - shortroomid: ShortRoomId, - - /// Shorteventid integer - shorteventid: ShortEventId, - }, - /// Attempts to retrieve a PDU from a remote server. **Does not** insert /// it into the database /// or persist it anywhere. @@ -109,20 +93,6 @@ pub enum DebugCommand { event_id: OwnedEventId, }, - /// Prints the very first PDU in the specified room (typically - /// m.room.create) - FirstPduInRoom { - /// The room ID - room_id: OwnedRoomId, - }, - - /// Prints the latest ("last") PDU in the specified room (typically a - /// message) - LatestPduInRoom { - /// The room ID - room_id: OwnedRoomId, - }, - /// Forcefully replaces the room state of our local copy of the specified /// room, with the copy (auth chain and room state events) the specified /// remote server says. diff --git a/src/admin/room/graph.rs b/src/admin/room/graph.rs index 988f64111..cdf1587c4 100644 --- a/src/admin/room/graph.rs +++ b/src/admin/room/graph.rs @@ -1,8 +1,8 @@ use clap::Subcommand; -use conduwuit::{Err, Event, Result, utils::stream::BroadbandExt}; +use conduwuit::{Err, Event, Result, err, utils::stream::BroadbandExt}; use conduwuit_macros::admin_command_dispatch; use futures::StreamExt; -use ruma::OwnedRoomOrAliasId; +use ruma::{OwnedEventId, OwnedRoomId, OwnedRoomOrAliasId}; #[admin_command_dispatch] #[derive(Debug, Subcommand)] @@ -11,6 +11,26 @@ pub enum GraphCommand { ListExtremities { room: OwnedRoomOrAliasId, }, + + /// Fetches a PDU (event) by its event ID, as stored in the database. Also + /// includes details about the PDU state. + GetPDU { + event_id: OwnedEventId, + }, + + /// Yields the first PDU we became aware of in a room. + /// This is always the room's create event for local rooms, or the first + /// membership event that introduced us to the remote room. + #[clap(name = "first-pdu")] + FirstPduInRoom { + room_id: OwnedRoomId, + }, + + /// Yields the most recent PDU in a room. + #[clap(name = "latest-pdu")] + LatestPduInRoom { + room_id: OwnedRoomId, + }, } impl crate::Context<'_> { @@ -54,4 +74,83 @@ impl crate::Context<'_> { Ok(()) } + + pub(super) async fn get_pdu(&self, event_id: OwnedEventId) -> Result { + let mut outlier = false; + let mut pdu_json = self + .services + .rooms + .timeline + .get_non_outlier_pdu_json(&event_id) + .await; + + if pdu_json.is_err() { + outlier = true; + pdu_json = self.services.rooms.timeline.get_pdu_json(&event_id).await; + } + let rejected = self + .services + .rooms + .pdu_metadata + .is_event_rejected(&event_id) + .await; + let soft_failed = self + .services + .rooms + .pdu_metadata + .is_event_soft_failed(&event_id) + .await; + + match pdu_json { + | Err(_) => return Err!("PDU not found locally."), + | Ok(json) => { + let text = serde_json::to_string_pretty(&json)?; + let msg = if rejected { + "Rejected PDU:" + } else if soft_failed { + "Soft-failed PDU:" + } else if outlier { + "Outlier PDU:" + } else { + "Timeline PDU:" + }; + write!(self, "{msg}\n```json\n{text}\n```") + }, + } + .await + } + + pub(super) async fn first_pdu_in_room(&self, room_id: OwnedRoomId) -> Result { + self.bail_restricted()?; + + let first_pdu = self + .services + .rooms + .timeline + .first_pdu_in_room(&room_id) + .await + .map(Event::into_canonical_object) + .and_then(|v| serde_json::to_string_pretty(&v).map_err(Into::into)) + .map_err(|e| err!(Database("Failed to find the first PDU in database: {e:?}")))?; + + let out = format!("```json\n{first_pdu}\n```"); + self.write_str(&out).await + } + + pub(super) async fn latest_pdu_in_room(&self, room_id: OwnedRoomId) -> Result { + self.bail_restricted()?; + + let latest_pdu = self + .services + .rooms + .timeline + .latest_pdu_in_room(&room_id) + .await + .map(Event::into_canonical_object) + .and_then(|v| serde_json::to_string_pretty(&v).map_err(Into::into)) + .map_err(|e| err!(Database("Failed to find the latest PDU in database: {e:?}")))?; + + let out = format!("```json\n{latest_pdu}\n```"); + self.write_str(&out).await + } }