From 2ac217ddd49d8bfc014025a5bc20a62ef34e9c56 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sat, 1 Aug 2026 00:20:55 +0000 Subject: [PATCH] feat: send messages to 5 relays instead of the newest 3 ones Otherwise users may add up to 5 relays, but 2 oldest relays are actually ignored. Having the maximum number of published relays and the number of relays used the same between all clients makes the order of relays in the key irrelevant. We may even remove sorting by `add_timestamp` from `get_all_self_addrs()` in the future. --- src/configure.rs | 37 ++++++++++++++++++++++++++++++++++++- src/pgp.rs | 11 +++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index cc8139cb3..589c7eb24 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -748,7 +748,7 @@ mod tests { use crate::config::Config; use crate::login_param::EnteredImapLoginParam; use crate::sql::update_transport_last_rcvd_timestamp; - use crate::test_utils::TestContext; + use crate::test_utils::{TestContext, TestContextManager}; use crate::transport::add_pseudo_transport; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -884,4 +884,39 @@ mod tests { Ok(()) } + + /// Tests that if Alice adds maximum number of transports, + /// Bob sends messages to all of them. + /// + /// This way we don't need to care about the order + /// of addresses advertised in the public key. + /// Previously the number of addresses + /// taken from the key was less than the maximum + /// number of advertised addresses. + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_can_send_to_max_relays() -> Result<()> { + let mut tcm = TestContextManager::new(); + + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + + // One relay is added already by default. + for i in 1..MAX_RELAYS { + add_pseudo_transport(alice, &format!("transport{i}@example.org")).await?; + } + assert_eq!(alice.count_transports().await?, MAX_RELAYS); + + let bob_chat_id = bob.create_chat_id(alice).await; + + bob.set_config_bool(Config::BccSelf, false).await?; + let sent = bob.send_text(bob_chat_id, "Hello!").await; + assert_eq!( + sent.recipients.split(' ').count(), + MAX_RELAYS, + "List of recipients is {}", + sent.recipients + ); + + Ok(()) + } } diff --git a/src/pgp.rs b/src/pgp.rs index 8821d3610..c4a50d5ea 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -23,6 +23,7 @@ use rand_old::{Rng as _, thread_rng}; use sha2::Sha256; use tokio::runtime::Handle; +use crate::configure::MAX_RELAYS; use crate::key::{DcKey, Fingerprint}; /// Preferred symmetric encryption algorithm. @@ -419,7 +420,13 @@ pub fn merge_openpgp_certificates( /// Returns relays addresses from the public key signature. /// -/// Not more than 3 relays are returned for each key. +/// Not more than [`MAX_RELAYS`] relays are returned for each key. +/// This is the same constant as the maximum number of published relays +/// the user is allowed to have in the key. +/// If the constant is changed in the future, +/// the client with the lower constant value +/// will ignore some relays advertised in the key, +/// but still send to the first [`MAX_RELAYS`]. pub(crate) fn addresses_from_public_key(public_key: &SignedPublicKey) -> Option> { for signature in &public_key.details.direct_signatures { // The signature should be verified already when importing the key, @@ -436,7 +443,7 @@ pub(crate) fn addresses_from_public_key(public_key: &SignedPublicKey) -> Option< .split(",") .map(|s| s.to_string()) .filter(|s| may_be_valid_addr(s)) - .take(3) + .take(MAX_RELAYS) .collect(), ); }