From 3618321efb711375b6b172e4a908b05a12ff57af Mon Sep 17 00:00:00 2001 From: Septias Date: Tue, 20 May 2025 16:24:44 +0200 Subject: [PATCH 01/14] add test --- src/peer_channels.rs | 81 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index 21aaacf036..a9197d4d3a 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -555,9 +555,9 @@ mod tests { use super::*; use crate::{ EventType, - chat::send_msg, message::{Message, Viewtype}, - test_utils::TestContextManager, + chat::{self, add_contact_to_chat, resend_msgs, send_msg, ChatId, ProtectionStatus}, + test_utils::{TestContext, TestContextManager}, }; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -924,8 +924,30 @@ mod tests { let alice = &mut tcm.alice().await; let bob = &mut tcm.bob().await; + let chat = alice.create_chat(&bob).await.id; + + let mut instance = Message::new(Viewtype::File); + instance + .set_file_from_bytes( + alice, + "minimal.xdc", + include_bytes!("../test-data/webxdc/minimal.xdc"), + None, + ) + .unwrap(); + connect_alice_bob(alice, bob, chat, &mut instance).await + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_webxdc_resend() { + let mut tcm = TestContextManager::new(); + let alice = &mut tcm.alice().await; + let bob = &mut tcm.bob().await; + let group = chat::create_group_chat(&alice, ProtectionStatus::Unprotected, "") + .await + .unwrap(); + // Alice sends webxdc to bob - let alice_chat = alice.create_chat(bob).await; let mut instance = Message::new(Viewtype::File); instance .set_file_from_bytes( @@ -935,7 +957,58 @@ mod tests { None, ) .unwrap(); - send_msg(alice, alice_chat.id, &mut instance).await.unwrap(); + + connect_alice_bob(alice, bob, group, &mut instance).await; + + // fiona joins late + let fiona = &mut tcm.fiona().await; + add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&bob).await) + .await + .unwrap(); + + add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&fiona).await) + .await + .unwrap(); + + resend_msgs(&alice, &[instance.id]).await.unwrap(); + let msg = alice.pop_sent_msg().await; + let fiona_instance = fiona.recv_msg(&msg).await.id; + + let fiona_connect_future = send_webxdc_realtime_advertisement(&fiona, fiona_instance) + .await + .unwrap() + .unwrap(); + let fiona_advert = fiona.pop_sent_msg().await; + alice.recv_msg_trash(&fiona_advert).await; + + fiona_connect_future.await.unwrap(); + send_webxdc_realtime_data(alice, instance.id, b"alice -> bob & fiona".into()) + .await + .unwrap(); + + eprintln!("Waiting for ephemeral message"); + loop { + let event = fiona.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == b"alice -> bob & fiona" { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + } + + async fn connect_alice_bob( + alice: &mut TestContext, + bob: &mut TestContext, + chat: ChatId, + instance: &mut Message, + ) { + send_msg(alice, chat, instance).await.unwrap(); let alice_webxdc = alice.get_last_msg().await; let webxdc = alice.pop_sent_msg().await; From bb5c10785a7681582ada2b651426b366c4bd09b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Wed, 21 May 2025 10:56:47 +0200 Subject: [PATCH 02/14] fix test --- src/peer_channels.rs | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index a9197d4d3a..975aac7241 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -943,7 +943,7 @@ mod tests { let mut tcm = TestContextManager::new(); let alice = &mut tcm.alice().await; let bob = &mut tcm.bob().await; - let group = chat::create_group_chat(&alice, ProtectionStatus::Unprotected, "") + let group = chat::create_group_chat(&alice, ProtectionStatus::Unprotected, "group chat") .await .unwrap(); @@ -958,13 +958,14 @@ mod tests { ) .unwrap(); + add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&bob).await) + .await + .unwrap(); + connect_alice_bob(alice, bob, group, &mut instance).await; // fiona joins late let fiona = &mut tcm.fiona().await; - add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&bob).await) - .await - .unwrap(); add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&fiona).await) .await @@ -972,9 +973,10 @@ mod tests { resend_msgs(&alice, &[instance.id]).await.unwrap(); let msg = alice.pop_sent_msg().await; - let fiona_instance = fiona.recv_msg(&msg).await.id; + let fiona_instance = fiona.recv_msg(&msg).await; + fiona_instance.chat_id.accept(&fiona).await.unwrap(); - let fiona_connect_future = send_webxdc_realtime_advertisement(&fiona, fiona_instance) + let fiona_connect_future = send_webxdc_realtime_advertisement(&fiona, fiona_instance.id) .await .unwrap() .unwrap(); @@ -987,19 +989,19 @@ mod tests { .unwrap(); eprintln!("Waiting for ephemeral message"); - loop { - let event = fiona.evtracker.recv().await.unwrap(); - if let EventType::WebxdcRealtimeData { data, .. } = event.typ { - if data == b"alice -> bob & fiona" { - break; - } else { - panic!( - "Unexpected status update: {}", - String::from_utf8_lossy(&data) - ); - } - } - } + // loop { + // let event = fiona.evtracker.recv().await.unwrap(); + // if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + // if data == b"alice -> bob & fiona" { + // break; + // } else { + // panic!( + // "Unexpected status update: {}", + // String::from_utf8_lossy(&data) + // ); + // } + // } + // } } async fn connect_alice_bob( From 495481b097553574f548984e2772a0f2d7fb3a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 22 May 2025 11:27:22 +0200 Subject: [PATCH 03/14] Do not use static strings --- src/mimefactory.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 8baa0ded9a..43c769eb22 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -21,8 +21,7 @@ use crate::contact::{Contact, ContactId, Origin}; use crate::context::Context; use crate::e2ee::EncryptHelper; use crate::ephemeral::Timer as EphemeralTimer; -use crate::key::self_fingerprint; -use crate::key::{DcKey, SignedPublicKey}; +use crate::key::{DcKey, self_fingerprint, SignedPublicKey}; use crate::location; use crate::log::{info, warn}; use crate::message::{Message, MsgId, Viewtype}; @@ -1492,7 +1491,7 @@ impl MimeFactory { } SystemMessage::IrohNodeAddr => { headers.push(( - "Iroh-Node-Addr", + HeaderDef::IrohNodeAddr.into(), mail_builder::headers::text::Text::new(serde_json::to_string( &context .get_or_try_init_peer_channel() @@ -1674,7 +1673,7 @@ impl MimeFactory { parts.push(context.build_status_update_part(json)); } else if msg.viewtype == Viewtype::Webxdc { headers.push(( - "Iroh-Gossip-Topic", + HeaderDef::IrohGossipTopic.into(), mail_builder::headers::raw::Raw::new(create_iroh_header(context, msg.id).await?) .into(), )); From 63ba7efaa4ac1752487214a63abc5c98021c28c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 22 May 2025 11:27:58 +0200 Subject: [PATCH 04/14] capitalize Iroh --- src/peer_channels.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index 975aac7241..0841c9eafc 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -48,13 +48,13 @@ use crate::mimeparser::SystemMessage; const PUBLIC_KEY_LENGTH: usize = 32; const PUBLIC_KEY_STUB: &[u8] = "static_string".as_bytes(); -/// Store iroh peer channels for the context. +/// Store Iroh peer channels for the context. #[derive(Debug)] pub struct Iroh { - /// iroh router needed for iroh peer channels. + /// Iroh router needed for Iroh peer channels. pub(crate) router: iroh::protocol::Router, - /// [Gossip] needed for iroh peer channels. + /// [Gossip] needed for Iroh peer channels. pub(crate) gossip: Gossip, /// Sequence numbers for gossip channels. From 44cb66c185214834ccaeade15e1ae3b6eecdabcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 22 May 2025 11:29:09 +0200 Subject: [PATCH 05/14] don't start iroh when adding peers late --- src/peer_channels.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index 0841c9eafc..63b77532f8 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -138,17 +138,13 @@ impl Iroh { Ok(Some(join_rx)) } - /// Add gossip peers to realtime channel if it is already active. - pub async fn maybe_add_gossip_peers(&self, topic: TopicId, peers: Vec) -> Result<()> { + /// Add gossip peer to realtime channel if it is already active. + pub async fn maybe_add_gossip_peer(&self, topic: TopicId, peer: NodeAddr) -> Result<()> { if self.iroh_channels.read().await.get(&topic).is_some() { - for peer in &peers { - self.router.endpoint().add_node_addr(peer.clone())?; - } + self.router.endpoint().add_node_addr(peer.clone())?; - self.gossip.subscribe_with_opts( - topic, - JoinOptions::with_bootstrap(peers.into_iter().map(|peer| peer.node_id)), - ); + self.gossip + .subscribe_with_opts(topic, JoinOptions::with_bootstrap(vec![peer.node_id])); } Ok(()) } @@ -316,6 +312,14 @@ impl Context { } } } + + pub(crate) async fn maybe_add_gossip_peer(&self, topic: TopicId, peer: NodeAddr) -> Result<()> { + if let Some(iroh) = &*self.iroh.read().await { + info!(self, "Adding (maybe existing) peer to gossip: {peer:?}"); + iroh.maybe_add_gossip_peer(topic, peer).await?; + } + Ok(()) + } } /// Cache a peers [NodeId] for one topic. @@ -336,6 +340,7 @@ pub(crate) async fn iroh_add_peer_for_topic( } /// Add gossip peer from `Iroh-Node-Addr` header to WebXDC message identified by `instance_id`. +/// This should not start iroh, because receiving a NodeAddr does not mean you want to participate. pub async fn add_gossip_peer_from_header( context: &Context, instance_id: MsgId, @@ -371,8 +376,7 @@ pub async fn add_gossip_peer_from_header( let relay_server = node_addr.relay_url().map(|relay| relay.as_str()); iroh_add_peer_for_topic(context, instance_id, topic, node_id, relay_server).await?; - let iroh = context.get_or_try_init_peer_channel().await?; - iroh.maybe_add_gossip_peers(topic, vec![node_addr]).await?; + context.maybe_add_gossip_peer(topic, node_addr).await?; Ok(()) } From e199f20b21ad3947c359ded3d917b3832816862e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 22 May 2025 11:29:45 +0200 Subject: [PATCH 06/14] change function visibility --- src/peer_channels.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index 63b77532f8..d4586cbf94 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -194,7 +194,7 @@ impl Iroh { } /// Leave the realtime channel for a given topic. - pub(crate) async fn leave_realtime(&self, topic: TopicId) -> Result<()> { + pub async fn leave_realtime(&self, topic: TopicId) -> Result<()> { if let Some(channel) = self.iroh_channels.write().await.remove(&topic) { // Dropping the last GossipTopic results in quitting the topic. // It is split into GossipReceiver and GossipSender. @@ -323,7 +323,7 @@ impl Context { } /// Cache a peers [NodeId] for one topic. -pub(crate) async fn iroh_add_peer_for_topic( +pub async fn iroh_add_peer_for_topic( ctx: &Context, msg_id: MsgId, topic: TopicId, @@ -381,7 +381,7 @@ pub async fn add_gossip_peer_from_header( } /// Insert topicId into the database so that we can use it to retrieve the topic. -pub(crate) async fn insert_topic_stub(ctx: &Context, msg_id: MsgId, topic: TopicId) -> Result<()> { +pub async fn insert_topic_stub(ctx: &Context, msg_id: MsgId, topic: TopicId) -> Result<()> { ctx.sql .execute( "INSERT OR REPLACE INTO iroh_gossip_peers (msg_id, public_key, topic, relay_server) VALUES (?, ?, ?, ?)", From 9e5a4d4415f4e27019b64d0587dc1101daae34ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 22 May 2025 11:41:54 +0200 Subject: [PATCH 07/14] improve logs --- src/peer_channels.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index d4586cbf94..bc336c468b 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -315,7 +315,10 @@ impl Context { pub(crate) async fn maybe_add_gossip_peer(&self, topic: TopicId, peer: NodeAddr) -> Result<()> { if let Some(iroh) = &*self.iroh.read().await { - info!(self, "Adding (maybe existing) peer to gossip: {peer:?}"); + info!( + self, + "Adding (maybe existing) peer with id {} to gossip", peer.node_id + ); iroh.maybe_add_gossip_peer(topic, peer).await?; } Ok(()) @@ -353,12 +356,13 @@ pub async fn add_gossip_peer_from_header( return Ok(()); } + let node_addr = + serde_json::from_str::(node_addr).context("Failed to parse node address")?; + info!( context, - "Adding iroh peer with address {node_addr:?} to the topic of {instance_id}." + "Adding iroh peer with node id {} to the topic of {instance_id}.", node_addr.node_id ); - let node_addr = - serde_json::from_str::(node_addr).context("Failed to parse node address")?; context.emit_event(EventType::WebxdcRealtimeAdvertisementReceived { msg_id: instance_id, From 082ac3a703dee3f1538b41ccb9ea3e2aad158519 Mon Sep 17 00:00:00 2001 From: Septias Date: Mon, 7 Jul 2025 13:44:12 +0200 Subject: [PATCH 08/14] fix: use initial topic on resend --- src/mimefactory.rs | 21 +++++++++++++++++---- src/peer_channels.rs | 27 ++++++++++++++++++--------- src/receive_imf.rs | 2 +- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 43c769eb22..d48379a06a 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -5,7 +5,11 @@ use std::io::Cursor; use anyhow::{Context as _, Result, bail, ensure}; use base64::Engine as _; +use chrono::TimeZone; +use data_encoding::BASE32_NOPAD; use deltachat_contact_tools::sanitize_bidi_characters; +use iroh_gossip::proto::TopicId; +use mail_builder::headers::address::{Address, EmailAddress}; use mail_builder::headers::HeaderType; use mail_builder::headers::address::{Address, EmailAddress}; use mail_builder::mime::MimePart; @@ -27,7 +31,8 @@ use crate::log::{info, warn}; use crate::message::{Message, MsgId, Viewtype}; use crate::mimeparser::{SystemMessage, is_hidden}; use crate::param::Param; -use crate::peer_channels::create_iroh_header; +use crate::peer_channels::{create_iroh_header, get_iroh_topic_for_msg}; +use crate::peerstate::Peerstate; use crate::simplify::escape_message_footer_marks; use crate::stock_str; use crate::tools::{ @@ -138,6 +143,9 @@ pub struct MimeFactory { /// True if the avatar should be attached. pub attach_selfavatar: bool, + + /// Sustain webxdc topic on resend. + webxdc_topic: Option, } /// Result of rendering a message, ready to be submitted to a send job. @@ -448,7 +456,7 @@ impl MimeFactory { member_timestamps.is_empty() || to.len() + past_members.len() == member_timestamps.len() ); - + let webxdc_topic = get_iroh_topic_for_msg(context, msg.id).await?; let factory = MimeFactory { from_addr, from_displayname, @@ -468,6 +476,7 @@ impl MimeFactory { last_added_location_id: None, sync_ids_to_delete: None, attach_selfavatar, + webxdc_topic, }; Ok(factory) } @@ -515,6 +524,7 @@ impl MimeFactory { last_added_location_id: None, sync_ids_to_delete: None, attach_selfavatar: false, + webxdc_topic: None, }; Ok(res) @@ -1672,10 +1682,13 @@ impl MimeFactory { let json = msg.param.get(Param::Arg).unwrap_or_default(); parts.push(context.build_status_update_part(json)); } else if msg.viewtype == Viewtype::Webxdc { + let topic = self + .webxdc_topic + .map(|top| BASE32_NOPAD.encode(top.as_bytes()).to_ascii_lowercase()) + .unwrap_or(create_iroh_header(context, msg.id).await?); headers.push(( HeaderDef::IrohGossipTopic.into(), - mail_builder::headers::raw::Raw::new(create_iroh_header(context, msg.id).await?) - .into(), + mail_builder::headers::raw::Raw::new(topic).into(), )); if let (Some(json), _) = context .render_webxdc_status_update_object( diff --git a/src/peer_channels.rs b/src/peer_channels.rs index bc336c468b..ce2897fb64 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -109,7 +109,7 @@ impl Iroh { info!( ctx, - "IROH_REALTIME: Joining gossip with peers: {:?}", node_ids, + "IROH_REALTIME: Joining gossip {topic} with peers: {:?}", node_ids, ); // Inform iroh of potentially new node addresses @@ -142,11 +142,11 @@ impl Iroh { pub async fn maybe_add_gossip_peer(&self, topic: TopicId, peer: NodeAddr) -> Result<()> { if self.iroh_channels.read().await.get(&topic).is_some() { self.router.endpoint().add_node_addr(peer.clone())?; - - self.gossip - .subscribe_with_opts(topic, JoinOptions::with_bootstrap(vec![peer.node_id])); + self.gossip.subscribe(topic, vec![peer.node_id])?; + Ok(()) + } else { + anyhow::bail!("can not read iroh channels"); } - Ok(()) } /// Send realtime data to the gossip swarm. @@ -317,7 +317,7 @@ impl Context { if let Some(iroh) = &*self.iroh.read().await { info!( self, - "Adding (maybe existing) peer with id {} to gossip", peer.node_id + "Adding (maybe existing) peer with id {} to {topic}", peer.node_id ); iroh.maybe_add_gossip_peer(topic, peer).await?; } @@ -560,6 +560,10 @@ async fn subscribe_loop( #[cfg(test)] mod tests { + use std::time::Duration; + + use tokio::time::timeout; + use super::*; use crate::{ EventType, @@ -991,7 +995,10 @@ mod tests { let fiona_advert = fiona.pop_sent_msg().await; alice.recv_msg_trash(&fiona_advert).await; - fiona_connect_future.await.unwrap(); + timeout(Duration::from_secs(2), fiona_connect_future) + .await + .unwrap() + .unwrap(); send_webxdc_realtime_data(alice, instance.id, b"alice -> bob & fiona".into()) .await .unwrap(); @@ -1035,8 +1042,9 @@ mod tests { .unwrap(); let alice_advertisement = alice.pop_sent_msg().await; - send_webxdc_realtime_advertisement(bob, bob_webxdc.id) + let bob_advertisement_future = send_webxdc_realtime_advertisement(bob, bob_webxdc.id) .await + .unwrap() .unwrap(); let bob_advertisement = bob.pop_sent_msg().await; @@ -1044,8 +1052,9 @@ mod tests { bob.recv_msg_trash(&alice_advertisement).await; alice.recv_msg_trash(&bob_advertisement).await; - eprintln!("Alice waits for connection"); + eprintln!("Alice and Bob wait for connection"); alice_advertisement_future.await.unwrap(); + bob_advertisement_future.await.unwrap(); // Alice sends ephemeral message eprintln!("Sending ephemeral message"); diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 131167ad9f..f20cf2210f 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -2141,7 +2141,7 @@ RETURNING id created_db_entries.push(row_id); } - // check all parts whether they contain a new logging webxdc + // Maybe set logging xdc and add gossip topics for webxdcs. for (part, msg_id) in mime_parser.parts.iter().zip(&created_db_entries) { // check if any part contains a webxdc topic id if part.typ == Viewtype::Webxdc { From bad8676ae67023be21f94ff0bc5ae2dce026d603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Tue, 8 Jul 2025 11:45:38 +0200 Subject: [PATCH 09/14] fixup rebase --- src/mimefactory.rs | 5 ++--- src/peer_channels.rs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index d48379a06a..a65e12fe33 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -9,7 +9,6 @@ use chrono::TimeZone; use data_encoding::BASE32_NOPAD; use deltachat_contact_tools::sanitize_bidi_characters; use iroh_gossip::proto::TopicId; -use mail_builder::headers::address::{Address, EmailAddress}; use mail_builder::headers::HeaderType; use mail_builder::headers::address::{Address, EmailAddress}; use mail_builder::mime::MimePart; @@ -25,14 +24,14 @@ use crate::contact::{Contact, ContactId, Origin}; use crate::context::Context; use crate::e2ee::EncryptHelper; use crate::ephemeral::Timer as EphemeralTimer; -use crate::key::{DcKey, self_fingerprint, SignedPublicKey}; +use crate::headerdef::HeaderDef; +use crate::key::{DcKey, SignedPublicKey, self_fingerprint}; use crate::location; use crate::log::{info, warn}; use crate::message::{Message, MsgId, Viewtype}; use crate::mimeparser::{SystemMessage, is_hidden}; use crate::param::Param; use crate::peer_channels::{create_iroh_header, get_iroh_topic_for_msg}; -use crate::peerstate::Peerstate; use crate::simplify::escape_message_footer_marks; use crate::stock_str; use crate::tools::{ diff --git a/src/peer_channels.rs b/src/peer_channels.rs index ce2897fb64..c939a1809a 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -567,8 +567,8 @@ mod tests { use super::*; use crate::{ EventType, + chat::{self, ChatId, ProtectionStatus, add_contact_to_chat, resend_msgs, send_msg}, message::{Message, Viewtype}, - chat::{self, add_contact_to_chat, resend_msgs, send_msg, ChatId, ProtectionStatus}, test_utils::{TestContext, TestContextManager}, }; From 0e01fa14c06e8e0bbc54f35dd786ae2bfcb7b0b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Tue, 8 Jul 2025 12:39:43 +0200 Subject: [PATCH 10/14] clippy fixes --- src/peer_channels.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index c939a1809a..f045fecae9 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -936,7 +936,7 @@ mod tests { let alice = &mut tcm.alice().await; let bob = &mut tcm.bob().await; - let chat = alice.create_chat(&bob).await.id; + let chat = alice.create_chat(bob).await.id; let mut instance = Message::new(Viewtype::File); instance @@ -955,7 +955,7 @@ mod tests { let mut tcm = TestContextManager::new(); let alice = &mut tcm.alice().await; let bob = &mut tcm.bob().await; - let group = chat::create_group_chat(&alice, ProtectionStatus::Unprotected, "group chat") + let group = chat::create_group_chat(alice, ProtectionStatus::Unprotected, "group chat") .await .unwrap(); @@ -970,7 +970,7 @@ mod tests { ) .unwrap(); - add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&bob).await) + add_contact_to_chat(alice, group, alice.add_or_lookup_contact_id(bob).await) .await .unwrap(); @@ -979,16 +979,16 @@ mod tests { // fiona joins late let fiona = &mut tcm.fiona().await; - add_contact_to_chat(&alice, group, alice.add_or_lookup_contact_id(&fiona).await) + add_contact_to_chat(alice, group, alice.add_or_lookup_contact_id(fiona).await) .await .unwrap(); - resend_msgs(&alice, &[instance.id]).await.unwrap(); + resend_msgs(alice, &[instance.id]).await.unwrap(); let msg = alice.pop_sent_msg().await; let fiona_instance = fiona.recv_msg(&msg).await; - fiona_instance.chat_id.accept(&fiona).await.unwrap(); + fiona_instance.chat_id.accept(fiona).await.unwrap(); - let fiona_connect_future = send_webxdc_realtime_advertisement(&fiona, fiona_instance.id) + let fiona_connect_future = send_webxdc_realtime_advertisement(fiona, fiona_instance.id) .await .unwrap() .unwrap(); From 3d9486e88ac6e1c94fa202c480783c9ea045eda4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 10 Jul 2025 09:50:47 +0200 Subject: [PATCH 11/14] enable last check --- src/peer_channels.rs | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index f045fecae9..64c211130d 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -143,10 +143,8 @@ impl Iroh { if self.iroh_channels.read().await.get(&topic).is_some() { self.router.endpoint().add_node_addr(peer.clone())?; self.gossip.subscribe(topic, vec![peer.node_id])?; - Ok(()) - } else { - anyhow::bail!("can not read iroh channels"); } + Ok(()) } /// Send realtime data to the gossip swarm. @@ -560,10 +558,6 @@ async fn subscribe_loop( #[cfg(test)] mod tests { - use std::time::Duration; - - use tokio::time::timeout; - use super::*; use crate::{ EventType, @@ -571,6 +565,8 @@ mod tests { message::{Message, Viewtype}, test_utils::{TestContext, TestContextManager}, }; + use std::time::Duration; + use tokio::time::timeout; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_can_communicate() { @@ -1003,20 +999,23 @@ mod tests { .await .unwrap(); - eprintln!("Waiting for ephemeral message"); - // loop { - // let event = fiona.evtracker.recv().await.unwrap(); - // if let EventType::WebxdcRealtimeData { data, .. } = event.typ { - // if data == b"alice -> bob & fiona" { - // break; - // } else { - // panic!( - // "Unexpected status update: {}", - // String::from_utf8_lossy(&data) - // ); - // } - // } - // } + timeout(Duration::from_secs(2), async { + loop { + let event = fiona.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == b"alice -> bob & fiona" { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + }) + .await + .unwrap(); } async fn connect_alice_bob( From 2d12aeccdd41d8abf8229b7200b3a1276c4f0f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Thu, 10 Jul 2025 09:58:30 +0200 Subject: [PATCH 12/14] remove timezone (rebase artifact) --- src/mimefactory.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index a65e12fe33..356e97be21 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -5,7 +5,6 @@ use std::io::Cursor; use anyhow::{Context as _, Result, bail, ensure}; use base64::Engine as _; -use chrono::TimeZone; use data_encoding::BASE32_NOPAD; use deltachat_contact_tools::sanitize_bidi_characters; use iroh_gossip::proto::TopicId; From d08b8287a0fbf02817a139018c2d10e6ba79b488 Mon Sep 17 00:00:00 2001 From: Septias Date: Sun, 13 Jul 2025 13:14:47 +0200 Subject: [PATCH 13/14] update comment --- src/mimefactory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 356e97be21..ac796a7074 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -142,7 +142,7 @@ pub struct MimeFactory { /// True if the avatar should be attached. pub attach_selfavatar: bool, - /// Sustain webxdc topic on resend. + /// This field is used to sustain the topic id of webxdcs needed for peer channels. webxdc_topic: Option, } From a8da6779c1dc34ed7d2bd902ecf95666ef0da560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= Date: Sun, 13 Jul 2025 14:37:08 +0200 Subject: [PATCH 14/14] remove timout --- src/peer_channels.rs | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/peer_channels.rs b/src/peer_channels.rs index 64c211130d..7941739517 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -565,8 +565,6 @@ mod tests { message::{Message, Viewtype}, test_utils::{TestContext, TestContextManager}, }; - use std::time::Duration; - use tokio::time::timeout; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_can_communicate() { @@ -991,31 +989,24 @@ mod tests { let fiona_advert = fiona.pop_sent_msg().await; alice.recv_msg_trash(&fiona_advert).await; - timeout(Duration::from_secs(2), fiona_connect_future) - .await - .unwrap() - .unwrap(); + fiona_connect_future.await.unwrap(); send_webxdc_realtime_data(alice, instance.id, b"alice -> bob & fiona".into()) .await .unwrap(); - timeout(Duration::from_secs(2), async { - loop { - let event = fiona.evtracker.recv().await.unwrap(); - if let EventType::WebxdcRealtimeData { data, .. } = event.typ { - if data == b"alice -> bob & fiona" { - break; - } else { - panic!( - "Unexpected status update: {}", - String::from_utf8_lossy(&data) - ); - } + loop { + let event = fiona.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == b"alice -> bob & fiona" { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); } } - }) - .await - .unwrap(); + } } async fn connect_alice_bob(