feat: Basic multi-relay onboarding (#8444)

If multi-relay onboarding config is set from UIs, automatically add
relays until there are 3 relays. For now, there will be a hardcoded list
of relay candidates.

- We need a list of chatmail relays that we somehow trust, and that
agree to be in the list. Then, we add all of them to the candidate list
(a new SQL table with colums "host" and "last_tried").
- Before going to IMAP IDLE: When there are less than 3 relays, fill it
up with relays from the candidate list. If creating an account fails,
try again with another relay from the list. For each candidate, we need
to remember the last time we tried to add a transport there, and try at
most once a week or so per candidate.
- For now, this will be behind an off-by-default config option, which at
least DC Android will enable when creating a new profile. UIs can then
opt in on their own pace but will likely need to disable it for tests.
- Right now, the backoff times are: Try to add a relay at most once per
hour, and try to add the same relay at most once per week
This commit is contained in:
Hocuri
2026-07-31 13:14:43 +02:00
committed by GitHub
parent 9476f9ec7f
commit db13d08f6c
10 changed files with 604 additions and 91 deletions

View File

@@ -2534,6 +2534,39 @@ UPDATE msgs SET state=24 WHERE state=18; -- Change OutPreparing to OutFailed.
.await?;
}
inc_and_check(&mut migration_version, 161)?;
if dbversion < migration_version {
// TODO put a better list here
const DEFAULT_RELAY_CANDIDATES: &[&str] = &[
"mehl.cloud",
"mailchat.pl",
"chatmail.woodpeckersnest.space",
"chatmail.culturanerd.it",
"tarpit.fun",
"d.gaufr.es",
];
sql.execute_migration_transaction(
|transaction| {
transaction.execute(
"CREATE TABLE relay_candidates(
host TEXT PRIMARY KEY NOT NULL,
last_tried INTEGER NOT NULL DEFAULT 0
) STRICT",
(),
)?;
let mut statement =
transaction.prepare("INSERT INTO relay_candidates(host) VALUES (?)")?;
for host in DEFAULT_RELAY_CANDIDATES {
statement.execute((host,))?;
}
Ok(())
},
migration_version,
)
.await?;
}
let new_version = sql
.get_raw_config_int(VERSION_CFG)
.await?