mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 01:16:31 +03:00
fix: assign iroh gossip topic to pre-message when post-message is received
Iroh-Gossip-Topic is sent in a post-message. Post-message goes to trash, so topic should be associated with the existing pre-message that is updated rather than with the post-message.
This commit is contained in:
@@ -24,6 +24,13 @@ def path_to_webxdc(request):
|
|||||||
return str(p)
|
return str(p)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def path_to_large_webxdc(request):
|
||||||
|
p = request.path.parent.parent.parent.joinpath("test-data/webxdc/realtime-check.xdc")
|
||||||
|
assert p.exists()
|
||||||
|
return str(p)
|
||||||
|
|
||||||
|
|
||||||
def log(msg):
|
def log(msg):
|
||||||
logging.info(msg)
|
logging.info(msg)
|
||||||
|
|
||||||
@@ -227,3 +234,29 @@ def test_advertisement_after_chatting(acfactory, path_to_webxdc):
|
|||||||
ac2_webxdc_msg.send_webxdc_realtime_advertisement()
|
ac2_webxdc_msg.send_webxdc_realtime_advertisement()
|
||||||
event = ac1.wait_for_event(EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED)
|
event = ac1.wait_for_event(EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED)
|
||||||
assert event.msg_id == ac1_webxdc_msg.id
|
assert event.msg_id == ac1_webxdc_msg.id
|
||||||
|
|
||||||
|
|
||||||
|
def test_realtime_large_webxdc(acfactory, path_to_large_webxdc):
|
||||||
|
"""Tests initializing realtime channel on a large webxdc.
|
||||||
|
|
||||||
|
This is a regression test for a bug that existed in version 2.42.0.
|
||||||
|
Large webxdc is split into pre- and post- message,
|
||||||
|
and this previously resulted in failure to initialize realtime.
|
||||||
|
"""
|
||||||
|
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||||
|
ac1.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
ac2.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
|
||||||
|
ac2.create_chat(ac1)
|
||||||
|
ac1_ac2_chat = ac1.create_chat(ac2)
|
||||||
|
ac1_webxdc_msg = ac1_ac2_chat.send_message(text="realtime check", file=path_to_large_webxdc)
|
||||||
|
|
||||||
|
# Receive pre-message.
|
||||||
|
ac2_webxdc_msg = ac2.wait_for_incoming_msg()
|
||||||
|
|
||||||
|
# Receive post-message.
|
||||||
|
ac2_webxdc_msg = ac2.wait_for_msg(EventType.MSGS_CHANGED)
|
||||||
|
|
||||||
|
ac2_webxdc_msg.send_webxdc_realtime_advertisement()
|
||||||
|
event = ac1.wait_for_event(EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED)
|
||||||
|
assert event.msg_id == ac1_webxdc_msg.id
|
||||||
|
|||||||
@@ -521,6 +521,18 @@ pub(crate) async fn create_iroh_header(ctx: &Context, msg_id: MsgId) -> Result<S
|
|||||||
Ok(topic_string)
|
Ok(topic_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts `Iroh-Gossip-Header` contents to iroh topic ID.
|
||||||
|
pub(crate) fn iroh_topic_from_str(topic: &str) -> Result<TopicId> {
|
||||||
|
let mut topic_raw = [0u8; 32];
|
||||||
|
BASE32_NOPAD
|
||||||
|
.decode_mut(topic.to_ascii_uppercase().as_bytes(), &mut topic_raw)
|
||||||
|
.map_err(|e| e.error)
|
||||||
|
.context("Wrong gossip topic header")?;
|
||||||
|
|
||||||
|
let topic = TopicId::from_bytes(topic_raw);
|
||||||
|
Ok(topic)
|
||||||
|
}
|
||||||
|
|
||||||
async fn subscribe_loop(
|
async fn subscribe_loop(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
mut stream: iroh_gossip::net::GossipReceiver,
|
mut stream: iroh_gossip::net::GossipReceiver,
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ use std::iter;
|
|||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use anyhow::{Context as _, Result, ensure};
|
use anyhow::{Context as _, Result, ensure};
|
||||||
use data_encoding::BASE32_NOPAD;
|
|
||||||
use deltachat_contact_tools::{
|
use deltachat_contact_tools::{
|
||||||
ContactAddress, addr_cmp, addr_normalize, may_be_valid_addr, sanitize_bidi_characters,
|
ContactAddress, addr_cmp, addr_normalize, may_be_valid_addr, sanitize_bidi_characters,
|
||||||
sanitize_single_line,
|
sanitize_single_line,
|
||||||
};
|
};
|
||||||
use iroh_gossip::proto::TopicId;
|
|
||||||
use mailparse::SingleInfo;
|
use mailparse::SingleInfo;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@@ -39,7 +37,7 @@ use crate::mimeparser::{
|
|||||||
AvatarAction, GossipedKey, MimeMessage, PreMessageMode, SystemMessage, parse_message_ids,
|
AvatarAction, GossipedKey, MimeMessage, PreMessageMode, SystemMessage, parse_message_ids,
|
||||||
};
|
};
|
||||||
use crate::param::{Param, Params};
|
use crate::param::{Param, Params};
|
||||||
use crate::peer_channels::{add_gossip_peer_from_header, insert_topic_stub};
|
use crate::peer_channels::{add_gossip_peer_from_header, insert_topic_stub, iroh_topic_from_str};
|
||||||
use crate::reaction::{Reaction, set_msg_reaction};
|
use crate::reaction::{Reaction, set_msg_reaction};
|
||||||
use crate::rusqlite::OptionalExtension;
|
use crate::rusqlite::OptionalExtension;
|
||||||
use crate::securejoin::{
|
use crate::securejoin::{
|
||||||
@@ -2298,21 +2296,12 @@ RETURNING id
|
|||||||
|
|
||||||
// Maybe set logging xdc and add gossip topics for webxdcs.
|
// Maybe set logging xdc and add gossip topics for webxdcs.
|
||||||
for (part, msg_id) in mime_parser.parts.iter().zip(&created_db_entries) {
|
for (part, msg_id) in mime_parser.parts.iter().zip(&created_db_entries) {
|
||||||
// check if any part contains a webxdc topic id
|
if mime_parser.pre_message != PreMessageMode::Post
|
||||||
if part.typ == Viewtype::Webxdc {
|
&& part.typ == Viewtype::Webxdc
|
||||||
if let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic) {
|
&& let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic)
|
||||||
// default encoding of topic ids is `hex`.
|
{
|
||||||
let mut topic_raw = [0u8; 32];
|
let topic = iroh_topic_from_str(topic)?;
|
||||||
BASE32_NOPAD
|
|
||||||
.decode_mut(topic.to_ascii_uppercase().as_bytes(), &mut topic_raw)
|
|
||||||
.map_err(|e| e.error)
|
|
||||||
.context("Wrong gossip topic header")?;
|
|
||||||
|
|
||||||
let topic = TopicId::from_bytes(topic_raw);
|
|
||||||
insert_topic_stub(context, *msg_id, topic).await?;
|
insert_topic_stub(context, *msg_id, topic).await?;
|
||||||
} else {
|
|
||||||
warn!(context, "webxdc doesn't have a gossip topic")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_set_logging_xdc_inner(
|
maybe_set_logging_xdc_inner(
|
||||||
@@ -2517,6 +2506,13 @@ async fn handle_post_message(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if part.typ == Viewtype::Webxdc
|
||||||
|
&& let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic)
|
||||||
|
{
|
||||||
|
let topic = iroh_topic_from_str(topic)?;
|
||||||
|
insert_topic_stub(context, msg_id, topic).await?;
|
||||||
|
}
|
||||||
|
|
||||||
let mut new_params = original_msg.param.clone();
|
let mut new_params = original_msg.param.clone();
|
||||||
new_params
|
new_params
|
||||||
.merge_in_params(part.param.clone())
|
.merge_in_params(part.param.clone())
|
||||||
|
|||||||
BIN
test-data/webxdc/realtime-check.xdc
Normal file
BIN
test-data/webxdc/realtime-check.xdc
Normal file
Binary file not shown.
Reference in New Issue
Block a user