Document the implemented single-table member receive lifecycle

This commit is contained in:
evgeny committed 2026-11-04 00:58:51 +01:00
1 parent fc6dc6a93b
commit 0669cd7b06
1 file changed
+31 -14
+31 -14
View File
@@ -1,6 +1,6 @@
# member_sync — адаптер участников каналов
Поверх [merkle_sync](merkle_sync_doc.md) синхронизирует source=0 записи таблиц peers_<channel_id>
Поверх [merkle_sync](merkle_sync_doc.md) синхронизирует опубликованные source=0 записи таблиц peers_<channel_id>
и подписанную политику приглашений. Правила допуска и переподписи: [group_invite_policy](../../doc/group_invite_policy.txt).
Транспортный движок не занимается подписями и версиями участников.
@@ -27,10 +27,26 @@ ver — каноническая десятичная строка1..INT_MAX,б
Удаление используется для повреждённых записей. Конфликт одинаковых версий с разным содержимым
не разрешается порядком доставки: отсутствие прогресса завершает Merkle-раунд ошибкой конфликта.
Входящая страница сначала целиком проверяется на корректность раскладки, длин и строк.
Затем записи применяются под savepoint member_page. Ошибка откатывает всю страницу вместе с индексом.
Уведомления GUI/топологии и changed выполняются после commit. Производное admitted
при приёме страниц пересчитывается после MT_OK, с сохранением предыдущего допуска до этой точки.
Входящая страница целиком проверяется на раскладку, длины, строки и границы листа/курсора.
Новые версии сохраняются в той же peers-таблице: record_state=1, sync_id своего обмена,
previous_id прежней записи, sync_record с исходным wire. Служебная строка node_id=0
хранит подписанную политику; её AUTOINCREMENT id даёт уникальный sync_id.
Сервисы, GUI, исходящие страницы и Merkle видят только record_state=0.
После получения всех различий BEGIN IMMEDIATE копирует актуальные опубликованные строки
в бэкап record_state=2 этого обмена. Сравнение версий, проверка подписей/цепочек,
выбор новой записи или валидного бэкапа, admitted, общие идентичности и индексы
входят в одну транзакцию. Если обе версии неверны, удаляется только этот участник.
Подписанное исключение остаётся валидной записью; даже повреждение профиля не стирает
независимый более свежий owner-блок при его восстановлении. Исключение самого узла
закрывает доступ, но не удаляет остальные записи. Неполная цепочка или SQL/crypto-отказ
откатывают обмен без разрушения прежнего состава. Уведомления идут после commit.
Параллельные обмены не видят pending друг друга. Поздний обмен сравнивается с текущей,
а не начальной версией: свежие изменения и отзывы не откатываются. Отмена удаляет
только свой sync_id; перезапуск удаляет все незавершённые версии. Формат peers изменён
без миграции старых таблиц: неподдерживаемая схема явно отклоняется.
Каждый member_sync_apply_record также имеет savepoint, поэтому ошибка пересчёта не оставляет запись без индекса.
Неудачный ROLLBACK TO не сопровождается RELEASE частичных данных:собственная операция
пробует полный ROLLBACK,при чужой транзакции полный откат обязан выполнить caller.
@@ -75,7 +91,7 @@ CHAT-группы и уведомляет props-потребителей; общ
и повторно вызвать очистку; stop/destroy выполняются вне callbacks.
Локальный верификатор возвращает 1 (сохранить), 0 (доказанная порча), -1 (операционная ошибка).
Отсутствие подписи/ожидаемой зависимости сохраняет запись; отказ SQL/OpenSSL не считается
Отсутствие ожидаемой зависимости сохраняет запись; отказ SQL/OpenSSL не считается
доказательством неверной подписи. verify_signature отдельно различает
MS_VERIFY_DEFERRED и MS_VERIFY_ERROR. Проверка source=1 placeholders не выполняется.
verify_and_purge_all останавливается на первом отказе; атомарность — по каналу,
@@ -83,14 +99,15 @@ verify_and_purge_all останавливается на первом отказ
start отклоняет запрос до создания Merkle-сессии, без done callback.
Проверяются привязка node_id к X25519, доверенный Ed25519, подписи блока участника и владельца.
Для дерева приглашений родитель может прийти позже ребёнка; finish повторно проверяет зависимости
перед подтверждением корня. Это не отдельная карантинная таблица: промежуточные записи существуют в БД
до finish, поэтому MT_OK нельзя заменять фактом их присутствия.
finish проверяет имеющиеся ненулевые подписи непосредственных пригласивших;
отсутствующая зависимость допускает завершение сверки, но не допуск участника.
group_policy после сверки обходит цепочки от корней и рассчитывает admitted по текущим правам.
validate_pubkey и validate_peer проверяют наличие строки без фильтра source/deleted;
допуск CHAT-группы отдельно проверяет topo_node_sqlite_member_allowed.
Для дерева приглашений родитель может прийти позже ребёнка; commit_pull проверяет
целый полученный состав до публикации общих ключей. group_policy обходит цепочки от
корней и рассчитывает admitted по текущим правам. validate_peer требует живой CHAT-группы,
допуска self/peer и совпадения ключа участника с аутентифицированным ETCP.
validate_request разрешает лишь запрос к известному источнику с проверенным JOIN,
когда собственного допуска ещё нет. Источник самостоятельно проверяет право выдачи;
получатель не отдаёт хеши/записи в обратную сторону и проверяет результат после DONE.
validate_pubkey остаётся вспомогательной проверкой наличия опубликованной строки;
он не является разрешением на доступ.
author_key требует source=0/deleted=0, доверенный ключ, join и сертификат непосредственного пригласившего.
Возвращает ACTIVE, INACTIVE, PENDING, INVALID или ERROR; выходной ключ меняется только при ACTIVE.
PENDING означает недостающий ключ/сертификат, а не отзыв членства или ошибку SQLite/OpenSSL.