You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

5.3 KiB

member_sync — адаптер участников каналов

Поверх merkle_sync синхронизирует source=0 записи таблиц peers_<channel_id>. Транспортный движок не занимается подписями и версиями участников.

Использование

  • member_sync_init вызывается при инициализации chat_sync и перестраивает производный индекс.
  • member_sync_start подключает канал к пиру и запрашивает подтверждение совпадения данных.
  • member_sync_put изменяет локальную запись, атомарно обновляет индекс и после commit уведомляет движок.
  • Прямые broadcast/send_to не нужны: локальная версия возвращается второму узлу при обратном проходе.
  • cancel/destroy снимают ожидания; отдельного публичного API рассылки нет.

Записи и применение

У записи два независимо версионируемых блока: участник (join_ts, update_ts) и владелец (adm_tags.ver). Удаление используется для повреждённых записей. Конфликт одинаковых версий с разным содержимым не разрешается порядком доставки: отсутствие прогресса завершает Merkle-раунд ошибкой конфликта.

Входящая страница сначала целиком проверяется на корректность раскладки, длин и строк. Затем записи применяются под savepoint member_page. Ошибка откатывает всю страницу вместе с индексом. Уведомления GUI/топологии и changed выполняются после commit. Каждый member_sync_apply_record также имеет savepoint, поэтому ошибка пересчёта не оставляет запись без индекса. При внешней транзакции вызывающая сторона отвечает за changed после commit.

Проверяются привязка node_id к X25519, доверенный Ed25519, подписи блока участника и владельца. Для дерева приглашений родитель может прийти позже ребёнка; finish повторно проверяет зависимости перед подтверждением корня. Это не отдельная карантинная таблица: промежуточные записи существуют в БД до finish, поэтому MT_OK нельзя заменять фактом их присутствия.

Канонический хеш

SHA256 по полям: node_id:8, x25519:32, ed25519:32, join_sig:64, join_ts:8, update_sig:64, update_ts:8, userinfo_len:1, userinfo, adm_tags_len:2, adm_tags, adm_tags_sig:64, signed_by:8, signature:64.

Целые big-endian; отсутствующие подписи представлены нулями. userinfo ограничен 255 байтами, adm_tags — 8192 байтами UTF-8 без NUL. Длина adm_tags — uint16 big-endian. Хеш и подпись владельца покрывают весь adm_tags без обрезания. Хеш включает userinfo и дерево приглашений. Формат сообщений, подписываемых моделью, определяется build_join_msg/build_update_msg/build_sign_msg отдельно.

Страница на проводе

Начинается с count:2 big-endian. Далее count записей: node_id:8, x25519:32, ed25519:32, flags:1, при HAS_JOIN — join_sig:64 и join_ts:8, update_sig:64, update_ts:8, userinfo_len:1, userinfo, adm_tags_len:2, adm_tags, adm_tags_sig:64, signed_by:8, signature:64.

Целые big-endian. Встроенные NUL и хвостовые байты запрещены. get_page перечисляет только один лист, в возрастающем порядке node_id, строго после курсора. SQLite использует signed INTEGER; внутри одного листа знак ключей одинаков, поэтому SQL-порядок совпадает с unsigned. Следующая запись, не помещающаяся в буфер, остаётся для следующей страницы. Ошибки SQL и повреждённые размеры BLOB возвращаются вызывающему коду.

Диагностика

Категория member_sync: ошибки содержат канал, node_id и причину отказа. DEBUG показывает применение версий и размеры страниц, TRACE — входы и расчёт листа. Хеши родителей вычисляет merkle_tree; адаптер никогда не перечисляет все записи для внутреннего узла.