Skip to content

Commit

Permalink
feat: add simple peer channels
Browse files Browse the repository at this point in the history
  • Loading branch information
Septias authored and Septias committed Mar 14, 2024
1 parent 76bbd5f commit 8c2d9b3
Show file tree
Hide file tree
Showing 15 changed files with 1,952 additions and 32 deletions.
1,422 changes: 1,398 additions & 24 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ hex = "0.4.0"
hickory-resolver = "0.24"
humansize = "2"
image = { version = "0.24.9", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
iroh = { version = "0.4.2", default-features = false }
iroh = { git = "https://github.com/deltachat/iroh", branch = "0.4-update-quic", default-features = false }
iroh-net = { git = "https://github.com/n0-computer/iroh", branch = "main" }
iroh-base = { git = "https://github.com/n0-computer/iroh", branch = "main" }
iroh-gossip = { git = "https://github.com/n0-computer/iroh", branch = "main", features = ["net"] }
quinn = "0.10"
kamadak-exif = "0.5"
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
libc = "0.2"
Expand Down
21 changes: 21 additions & 0 deletions deltachat-jsonrpc/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,27 @@ impl CommandApi {
.await
}

async fn send_webxdc_ephemeral_status_update(
&self,
account_id: u32,
instance_msg_id: u32,
update_str: String,
) -> Result<()> {
let ctx = self.get_context(account_id).await?;
ctx.send_webxdc_ephemeral_status_update(MsgId::new(instance_msg_id), &update_str)
.await
}

async fn send_webxdc_gossip_advertisement(
&self,
account_id: u32,
instance_msg_id: u32,
) -> Result<()> {
let ctx = self.get_context(account_id).await?;
ctx.send_gossip_advertisement(&MsgId::new(instance_msg_id))
.await
}

async fn get_webxdc_status_updates(
&self,
account_id: u32,
Expand Down
10 changes: 10 additions & 0 deletions deltachat-jsonrpc/src/api/types/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ pub enum EventType {
status_update_serial: u32,
},

#[serde(rename_all = "camelCase")]
WebxdcEphemeralStatusUpdate { msg_id: u32, status_update: String },

/// Inform that a message containing a webxdc instance has been deleted
#[serde(rename_all = "camelCase")]
WebxdcInstanceDeleted { msg_id: u32 },
Expand Down Expand Up @@ -357,6 +360,13 @@ impl From<CoreEventType> for EventType {
msg_id: msg_id.to_u32(),
status_update_serial: status_update_serial.to_u32(),
},
CoreEventType::WebxdcEphemeralStatusUpdate {
msg_id,
status_update,
} => WebxdcEphemeralStatusUpdate {
msg_id: msg_id.to_u32(),
status_update,
},
CoreEventType::WebxdcInstanceDeleted { msg_id } => WebxdcInstanceDeleted {
msg_id: msg_id.to_u32(),
},
Expand Down
3 changes: 3 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ pub enum Config {
/// This key is sent to the self_reporting bot so that the bot can recognize the user
/// without storing the email address
SelfReportingId,

/// Iroh secret key.
IrohSecretKey,
}

impl Config {
Expand Down
32 changes: 32 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ use crate::sql::Sql;
use crate::stock_str::StockStrings;
use crate::timesmearing::SmearedTimestamp;
use crate::tools::{self, create_id, duration_to_str, time, time_elapsed};
use iroh_gossip::net::Gossip;
use iroh_net::MagicEndpoint;

/// Builder for the [`Context`].
///
Expand Down Expand Up @@ -287,6 +289,12 @@ pub struct InnerContext {

/// True if account has subscribed to push notifications via IMAP.
pub(crate) push_subscribed: AtomicBool,

/// [MagicEndpoint] needed for iroh peer channels.
pub(crate) endpoint: Mutex<Option<MagicEndpoint>>,

/// [Gossip] needed for iroh peer channels.
pub(crate) gossip: Mutex<Option<Gossip>>,
}

/// The state of ongoing process.
Expand Down Expand Up @@ -444,6 +452,8 @@ impl Context {
debug_logging: std::sync::RwLock::new(None),
push_subscriber,
push_subscribed: AtomicBool::new(false),
endpoint: Mutex::new(None),
gossip: Mutex::new(None),
};

let ctx = Context {
Expand Down Expand Up @@ -473,11 +483,18 @@ impl Context {
*lock = Ratelimit::new(Duration::new(3, 0), 3.0);
}
}

if let Err(e) = self.create_gossip().await {
warn!(self, "{e}");
}

self.scheduler.start(self.clone()).await;
}

/// Stops the IO scheduler.
pub async fn stop_io(&self) {
self.endpoint.lock().await.take();
self.gossip.lock().await.take();
self.scheduler.stop(self).await;
}

Expand All @@ -489,6 +506,9 @@ impl Context {

/// Indicate that the network likely has come back.
pub async fn maybe_network(&self) {
if let Some(ref mut endpoint) = *self.endpoint.lock().await {
endpoint.network_change().await;
}
self.scheduler.maybe_network().await;
}

Expand Down Expand Up @@ -1621,6 +1641,7 @@ mod tests {
"socks5_user",
"socks5_password",
"key_id",
"iroh_secret_key",
];
let t = TestContext::new().await;
let info = t.get_info().await.unwrap();
Expand Down Expand Up @@ -1930,4 +1951,15 @@ mod tests {

Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_keypair_saving() -> Result<()> {
let alice = TestContext::new_alice().await;

let key = alice.get_or_generate_iroh_keypair().await?;
let loaded_key = alice.get_or_generate_iroh_keypair().await?;
assert_eq!(key.to_bytes(), loaded_key.to_bytes());

Ok(())
}
}
10 changes: 4 additions & 6 deletions src/debug_logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,10 @@ pub async fn debug_logging_loop(context: &Context, events: Receiver<DebugEventLo
}
Ok(serial) => {
if let Some(serial) = serial {
if !matches!(event, EventType::WebxdcStatusUpdate { .. }) {
context.emit_event(EventType::WebxdcStatusUpdate {
msg_id,
status_update_serial: serial,
});
}
context.emit_event(EventType::WebxdcStatusUpdate {
msg_id,
status_update_serial: serial,
});
} else {
// This should not happen as the update has no `uid`.
error!(context, "Debug logging update is not created.");
Expand Down
9 changes: 9 additions & 0 deletions src/events/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,15 @@ pub enum EventType {
status_update_serial: StatusUpdateSerial,
},

/// Webxdc ephemeral status update received.
WebxdcEphemeralStatusUpdate {
/// Message ID.
msg_id: MsgId,

/// Status update.
status_update: String,
},

/// Inform that a message containing a webxdc instance has been deleted.
WebxdcInstanceDeleted {
/// ID of the deleted message.
Expand Down
6 changes: 6 additions & 0 deletions src/headerdef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ pub enum HeaderDef {
/// See <https://datatracker.ietf.org/doc/html/rfc8601>
AuthenticationResults,

/// Public key to advertise to others.
IrohPublicKey,

/// Advertised gossip topic for one webxdc.
GossipTopic,

#[cfg(test)]
TestHeader,
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub mod receive_imf;
pub mod tools;

pub mod accounts;
pub mod peer_channels;
pub mod reaction;

/// If set IMAP/incoming and SMTP/outgoing MIME messages will be printed.
Expand Down
21 changes: 21 additions & 0 deletions src/mimefactory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ use crate::contact::Contact;
use crate::context::Context;
use crate::e2ee::EncryptHelper;
use crate::ephemeral::Timer as EphemeralTimer;
use crate::headerdef::HeaderDef;
use crate::html::new_html_mimepart;
use crate::location;
use crate::message::{self, Message, MsgId, Viewtype};
use crate::mimeparser::SystemMessage;
use crate::param::Param;
use crate::peer_channels::create_random_topic;
use crate::peerstate::Peerstate;
use crate::simplify::escape_message_footer_marks;
use crate::stock_str;
Expand Down Expand Up @@ -1121,6 +1123,12 @@ impl<'a> MimeFactory<'a> {
"protection-disabled".to_string(),
));
}
SystemMessage::IrohGossipAdvertisement => {
headers.protected.push(Header::new(
HeaderDef::IrohPublicKey.get_headername().to_string(),
serde_json::to_string(&context.get_iroh_node_addr().await?)?,
));
}
_ => {}
}

Expand Down Expand Up @@ -1277,6 +1285,19 @@ impl<'a> MimeFactory<'a> {
let json = self.msg.param.get(Param::Arg).unwrap_or_default();
parts.push(context.build_status_update_part(json));
} else if self.msg.viewtype == Viewtype::Webxdc {
let topic = create_random_topic();

context
.add_peer_for_topic(
self.msg.id,
topic,
context.get_iroh_node_addr().await.unwrap().node_id,
)
.await?;
headers.protected.push(Header::new(
HeaderDef::GossipTopic.get_headername().to_string(),
topic.to_string(),
));
if let Some(json) = context
.render_webxdc_status_update_object(self.msg.id, None)
.await?
Expand Down
3 changes: 3 additions & 0 deletions src/mimeparser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ pub enum SystemMessage {

/// Webxdc info added with `info` set in `send_webxdc_status_update()`.
WebxdcInfoMessage = 32,

/// This message contains a users iroh public key.
IrohGossipAdvertisement = 40,
}

const MIME_AC_SETUP_FILE: &str = "application/autocrypt-setup";
Expand Down
Loading

0 comments on commit 8c2d9b3

Please sign in to comment.