From 38affa2c62f210b64db617f159cc017cefa136d4 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Tue, 21 Apr 2026 10:38:10 -0300 Subject: [PATCH] fix: Don't resort re-sent message to the bottom (#8145) We shouldn't just revert ad7f873c68b0fa869d33a1e7ef22178c5f221260 because then we won't be able to normally transfer a backup from a device having clock a bit in the future. INDEXED BY msgs_index7 is to prevent SQLite from downgrading to using msgs_index2 which has less ordering. --- src/chat.rs | 6 ++++-- src/chat/chat_tests.rs | 43 ++++++++++++++++++++++++++++++++++++++++++ src/test_utils.rs | 21 ++++++++++++++------- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 966a041ca..ed1de6a89 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2947,17 +2947,19 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) - " UPDATE msgs SET timestamp=( - SELECT MAX(timestamp) FROM msgs WHERE + SELECT MAX(timestamp) FROM msgs INDEXED BY msgs_index7 WHERE -- From `InFresh` to `OutMdnRcvd` inclusive except `OutDraft`. state IN(10,13,16,18,20,24,26,28) AND hidden IN(0,1) AND - chat_id=? + chat_id=? AND + id<=? ), pre_rfc724_mid=?, subject=?, param=? WHERE id=? ", ( msg.chat_id, + msg.id, &msg.pre_rfc724_mid, &msg.subject, msg.param.to_string(), diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index b36f97490..36cf276d7 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -2692,6 +2692,49 @@ async fn test_resend_own_message() -> Result<()> { Ok(()) } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_resend_doesnt_resort_msg() -> Result<()> { + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let alice_grp = create_group(alice, "").await?; + let sent1 = alice.send_text(alice_grp, "hi").await; + let sent1_ts = Message::load_from_db(alice, sent1.sender_msg_id) + .await? + .timestamp_sort; + + SystemTime::shift(Duration::from_secs(60)); + add_contact_to_chat(alice, alice_grp, alice.add_or_lookup_contact_id(bob).await).await?; + let sent2 = alice + .send_text( + alice_grp, + "Let's test resending, there are very few tests on it", + ) + .await; + let resent_msg_id = sent1.sender_msg_id; + resend_msgs(alice, &[resent_msg_id]).await?; + assert_eq!( + resent_msg_id.get_state(alice).await?, + MessageState::OutPending + ); + alice.pop_sent_msg().await; + assert_eq!( + resent_msg_id.get_state(alice).await?, + MessageState::OutDelivered + ); + assert_eq!( + Message::load_from_db(alice, sent1.sender_msg_id) + .await? + .timestamp_sort, + sent1_ts + ); + assert_eq!( + alice.get_last_msg_id_in(alice_grp).await, + sent2.sender_msg_id + ); + Ok(()) +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_resend_foreign_message_fails() -> Result<()> { let mut tcm = TestContextManager::new(); diff --git a/src/test_utils.rs b/src/test_utils.rs index d946d7a7c..a365630b4 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -834,17 +834,24 @@ ORDER BY id" assert_eq!(received.chat_id, DC_CHAT_ID_TRASH); } + /// Gets the most recent message ID of a chat. + /// + /// Panics on errors or if the most recent message is a marker. + pub async fn get_last_msg_id_in(&self, chat_id: ChatId) -> MsgId { + let msgs = chat::get_chat_msgs(&self.ctx, chat_id).await.unwrap(); + if let ChatItem::Message { msg_id } = msgs.last().unwrap() { + *msg_id + } else { + panic!("Wrong item type"); + } + } + /// Gets the most recent message of a chat. /// /// Panics on errors or if the most recent message is a marker. pub async fn get_last_msg_in(&self, chat_id: ChatId) -> Message { - let msgs = chat::get_chat_msgs(&self.ctx, chat_id).await.unwrap(); - let msg_id = if let ChatItem::Message { msg_id } = msgs.last().unwrap() { - msg_id - } else { - panic!("Wrong item type"); - }; - Message::load_from_db(&self.ctx, *msg_id).await.unwrap() + let msg_id = self.get_last_msg_id_in(chat_id).await; + Message::load_from_db(&self.ctx, msg_id).await.unwrap() } /// Gets the most recent message over all chats.