core: chat relays protocol (#6383)

* core: chat relays protocol wip

* types, notes

* remove file

* removal protocol

* schema

* status

* update

* recovery

* update

* formatting

* rename

* more types

* comment

* more docs

* decrease number of steps

* format

* correct

* update

* update protocol

* update

* typo

* todo

* update doc

* update

* update

* remove added

* update

* update

* XGrpRelayReady

* link to chat relays

* update

* remove from protocol

* update

* json

* wip

* remove comment

* wip

* update

* wip

* wip

* update

* wip

* wip

* plans

* better view

* fix

* fix

* relay acceptance

* rework api

* add relays to link

* comment

* active on con, fix send

* comments

* direct in group plan

* prepare

* member connection wip

* comments

* member connection wip

* fix forwarding

* introduce moderators to new member

* enable relay tests

* plans

* security objectives

* refactor

* add to threat model

* stress test wip

* stress test wip

* Revert "stress test wip"

This reverts commit acde8a1fb3.

* Revert "stress test wip"

This reverts commit 6435808438.

* remove stress test

* improve output

* invert relay fkey

* postgres schema

* comments

* group in progress, remove auto-select relays commented code

* comments

* corrections

* comment

* lint

* redundant import

* core: chat relay request worker (#6509)

* update plans

* strict tables

* core: update group link asynchronously with relay link (#6548)

* update simplexmq

* docs: connection to chat relays rfc (#6554)

* add test for 2 relays (doesn't pass)

* create unknown member in same transaction as checking

* fix relays choosing different memberId (XContactRelay)

* plans, api

* use same incognito profile for relays, connect concurrently, save correct link for plan

* test

* don't duplicate items on group connection

* check relay record exists when joining

* use mapConcurrently when adding relays, update schemas

* fix multi-relay join for postgres (savepoint)

* core: async retry connection to chat relays (#6584)

* update simplexmq

* fix api tests

* prefer throwing temp error on connection

* check group relays when deleting from configuration

* relay_request_err_reason

* relay role

* rename, fix syntax

* plans

* rename, style

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
spaced4ndy
2026-01-21 13:19:06 +00:00
committed by GitHub
parent 2f1816ca32
commit bd8ba4d5c6
46 changed files with 3198 additions and 739 deletions
@@ -12,35 +12,81 @@ m20260109_chat_relays =
[r|
CREATE TABLE chat_relays(
chat_relay_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
address TEXT NOT NULL,
address BYTEA NOT NULL,
name TEXT NOT NULL,
domains TEXT NOT NULL,
preset SMALLINT NOT NULL DEFAULT 0,
tested SMALLINT,
enabled SMALLINT NOT NULL DEFAULT 1,
user_id BIGINT NOT NULL REFERENCES users ON DELETE CASCADE,
deleted SMALLINT NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT (now()),
updated_at TEXT NOT NULL DEFAULT (now()),
UNIQUE(user_id, address),
UNIQUE(user_id, name)
updated_at TEXT NOT NULL DEFAULT (now())
);
CREATE INDEX idx_chat_relays_user_id ON chat_relays(user_id);
CREATE UNIQUE INDEX idx_chat_relays_user_id_address ON chat_relays(user_id, address);
CREATE UNIQUE INDEX idx_chat_relays_user_id_name ON chat_relays(user_id, name);
ALTER TABLE users ADD COLUMN is_user_chat_relay SMALLINT NOT NULL DEFAULT 0;
ALTER TABLE group_members ADD COLUMN is_chat_relay SMALLINT NOT NULL DEFAULT 0;
ALTER TABLE groups
ADD COLUMN use_relays SMALLINT NOT NULL DEFAULT 0,
ADD COLUMN creating_in_progress SMALLINT NOT NULL DEFAULT 0,
ADD COLUMN relay_own_status TEXT,
ADD COLUMN relay_request_inv_id BYTEA,
ADD COLUMN relay_request_group_link BYTEA,
ADD COLUMN relay_request_peer_chat_min_version INTEGER,
ADD COLUMN relay_request_peer_chat_max_version INTEGER,
ADD COLUMN relay_request_failed SMALLINT DEFAULT 0,
ADD COLUMN relay_request_err_reason TEXT;
ALTER TABLE group_profiles ADD COLUMN group_link BYTEA;
CREATE TABLE group_relays(
group_relay_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
group_id BIGINT NOT NULL REFERENCES groups ON DELETE CASCADE,
group_member_id BIGINT NOT NULL REFERENCES group_members ON DELETE CASCADE,
chat_relay_id BIGINT NOT NULL REFERENCES chat_relays ON DELETE CASCADE,
relay_status TEXT NOT NULL,
relay_link BYTEA,
created_at TEXT NOT NULL DEFAULT (now()),
updated_at TEXT NOT NULL DEFAULT (now())
);
CREATE INDEX idx_group_relays_group_id ON group_relays(group_id);
CREATE UNIQUE INDEX idx_group_relays_group_member_id ON group_relays(group_member_id);
CREATE INDEX idx_group_relays_chat_relay_id ON group_relays(chat_relay_id);
ALTER TABLE group_members ADD COLUMN relay_link BYTEA;
|]
down_m20260109_chat_relays :: Text
down_m20260109_chat_relays =
T.pack
[r|
ALTER TABLE group_members DROP COLUMN is_chat_relay;
ALTER TABLE users DROP COLUMN is_user_chat_relay;
DROP INDEX idx_chat_relays_user_id;
ALTER TABLE groups
DROP COLUMN use_relays,
DROP COLUMN creating_in_progress,
DROP COLUMN relay_own_status,
DROP COLUMN relay_request_inv_id,
DROP COLUMN relay_request_group_link,
DROP COLUMN relay_request_peer_chat_min_version,
DROP COLUMN relay_request_peer_chat_max_version,
DROP COLUMN relay_request_failed,
DROP COLUMN relay_request_err_reason;
ALTER TABLE group_profiles DROP COLUMN group_link;
DROP INDEX idx_group_relays_group_id;
DROP INDEX idx_group_relays_group_member_id;
DROP INDEX idx_group_relays_chat_relay_id;
DROP TABLE group_relays;
DROP INDEX idx_chat_relays_user_id;
DROP INDEX idx_chat_relays_user_id_address;
DROP INDEX idx_chat_relays_user_id_name;
DROP TABLE chat_relays;
ALTER TABLE group_members DROP COLUMN relay_link;
|]
@@ -360,13 +360,14 @@ ALTER TABLE test_chat_schema.chat_items ALTER COLUMN chat_item_id ADD GENERATED
CREATE TABLE test_chat_schema.chat_relays (
chat_relay_id bigint NOT NULL,
address text NOT NULL,
address bytea NOT NULL,
name text NOT NULL,
domains text NOT NULL,
preset smallint DEFAULT 0 NOT NULL,
tested smallint,
enabled smallint DEFAULT 1 NOT NULL,
user_id bigint NOT NULL,
deleted smallint DEFAULT 0 NOT NULL,
created_at text DEFAULT now() NOT NULL,
updated_at text DEFAULT now() NOT NULL
);
@@ -809,7 +810,7 @@ CREATE TABLE test_chat_schema.group_members (
member_welcome_shared_msg_id bytea,
index_in_group bigint DEFAULT 0 NOT NULL,
member_relations_vector bytea,
is_chat_relay smallint DEFAULT 0 NOT NULL
relay_link bytea
);
@@ -837,7 +838,8 @@ CREATE TABLE test_chat_schema.group_profiles (
preferences text,
description text,
member_admission text,
short_descr text
short_descr text,
group_link bytea
);
@@ -853,6 +855,30 @@ ALTER TABLE test_chat_schema.group_profiles ALTER COLUMN group_profile_id ADD GE
CREATE TABLE test_chat_schema.group_relays (
group_relay_id bigint NOT NULL,
group_id bigint NOT NULL,
group_member_id bigint NOT NULL,
chat_relay_id bigint NOT NULL,
relay_status text NOT NULL,
relay_link bytea,
created_at text DEFAULT now() NOT NULL,
updated_at text DEFAULT now() NOT NULL
);
ALTER TABLE test_chat_schema.group_relays ALTER COLUMN group_relay_id ADD GENERATED ALWAYS AS IDENTITY (
SEQUENCE NAME test_chat_schema.group_relays_group_relay_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1
);
CREATE TABLE test_chat_schema.group_snd_item_statuses (
group_snd_item_status_id bigint NOT NULL,
chat_item_id bigint NOT NULL,
@@ -909,7 +935,16 @@ CREATE TABLE test_chat_schema.groups (
conn_link_prepared_connection smallint DEFAULT 0 NOT NULL,
via_group_link_uri bytea,
summary_current_members_count bigint DEFAULT 0 NOT NULL,
member_index bigint DEFAULT 0 NOT NULL
member_index bigint DEFAULT 0 NOT NULL,
use_relays smallint DEFAULT 0 NOT NULL,
creating_in_progress smallint DEFAULT 0 NOT NULL,
relay_own_status text,
relay_request_inv_id bytea,
relay_request_group_link bytea,
relay_request_peer_chat_min_version integer,
relay_request_peer_chat_max_version integer,
relay_request_failed smallint DEFAULT 0,
relay_request_err_reason text
);
@@ -1466,16 +1501,6 @@ ALTER TABLE ONLY test_chat_schema.chat_relays
ALTER TABLE ONLY test_chat_schema.chat_relays
ADD CONSTRAINT chat_relays_user_id_address_key UNIQUE (user_id, address);
ALTER TABLE ONLY test_chat_schema.chat_relays
ADD CONSTRAINT chat_relays_user_id_name_key UNIQUE (user_id, name);
ALTER TABLE ONLY test_chat_schema.chat_tags
ADD CONSTRAINT chat_tags_pkey PRIMARY KEY (chat_tag_id);
@@ -1591,6 +1616,11 @@ ALTER TABLE ONLY test_chat_schema.group_profiles
ALTER TABLE ONLY test_chat_schema.group_relays
ADD CONSTRAINT group_relays_pkey PRIMARY KEY (group_relay_id);
ALTER TABLE ONLY test_chat_schema.group_snd_item_statuses
ADD CONSTRAINT group_snd_item_statuses_pkey PRIMARY KEY (group_snd_item_status_id);
@@ -1968,6 +1998,14 @@ CREATE INDEX idx_chat_relays_user_id ON test_chat_schema.chat_relays USING btree
CREATE UNIQUE INDEX idx_chat_relays_user_id_address ON test_chat_schema.chat_relays USING btree (user_id, address);
CREATE UNIQUE INDEX idx_chat_relays_user_id_name ON test_chat_schema.chat_relays USING btree (user_id, name);
CREATE INDEX idx_chat_tags_chats_chat_tag_id ON test_chat_schema.chat_tags_chats USING btree (chat_tag_id);
@@ -2240,6 +2278,18 @@ CREATE INDEX idx_group_profiles_user_id ON test_chat_schema.group_profiles USING
CREATE INDEX idx_group_relays_chat_relay_id ON test_chat_schema.group_relays USING btree (chat_relay_id);
CREATE INDEX idx_group_relays_group_id ON test_chat_schema.group_relays USING btree (group_id);
CREATE UNIQUE INDEX idx_group_relays_group_member_id ON test_chat_schema.group_relays USING btree (group_member_id);
CREATE INDEX idx_group_snd_item_statuses_chat_item_id ON test_chat_schema.group_snd_item_statuses USING btree (chat_item_id);
@@ -2919,6 +2969,21 @@ ALTER TABLE ONLY test_chat_schema.group_profiles
ALTER TABLE ONLY test_chat_schema.group_relays
ADD CONSTRAINT group_relays_chat_relay_id_fkey FOREIGN KEY (chat_relay_id) REFERENCES test_chat_schema.chat_relays(chat_relay_id) ON DELETE CASCADE;
ALTER TABLE ONLY test_chat_schema.group_relays
ADD CONSTRAINT group_relays_group_id_fkey FOREIGN KEY (group_id) REFERENCES test_chat_schema.groups(group_id) ON DELETE CASCADE;
ALTER TABLE ONLY test_chat_schema.group_relays
ADD CONSTRAINT group_relays_group_member_id_fkey FOREIGN KEY (group_member_id) REFERENCES test_chat_schema.group_members(group_member_id) ON DELETE CASCADE;
ALTER TABLE ONLY test_chat_schema.group_snd_item_statuses
ADD CONSTRAINT group_snd_item_statuses_chat_item_id_fkey FOREIGN KEY (chat_item_id) REFERENCES test_chat_schema.chat_items(chat_item_id) ON DELETE CASCADE;