Replace history chain exchange with canonical Merkle data model
This commit is contained in:
1 parent
41c2a77fe6
commit
5e5ed41c19
2 files changed
+927
-1820
No files matched your search
+913
-1795
File diff suppressed because it is too large.
Load diff
+14
-25
@@ -1,6 +1,6 @@
|
||||
/* db_sync — репликация подписанных записей SQLite по прямым ETCP-соединениям.
|
||||
* Каждый DB_SYNC_INSTANCE связывает таблицу с group_id. Различия находятся по
|
||||
* цепочке хешей; новые записи рассылаются PUSH. Ключ и порядок записей:
|
||||
* общему Merkle-дереву; новые записи рассылаются PUSH. Ключ и порядок отображения:
|
||||
* (timestamp, author_signature). Подпись автора покрывает timestamp || data.
|
||||
* Ядро создаёт модуль, чат включает его и регистрирует таблицы каналов.
|
||||
* Обычно используется общая SQLite ядра; remove отключает таблицу от обмена,
|
||||
@@ -21,32 +21,15 @@ struct DB_SYNC_INSTANCE;
|
||||
// etcp service ID: ETCP_ID_DB_SYNC (etcp_bind, см. etcp_api.h)
|
||||
|
||||
// Message types
|
||||
#define DB_MSG_INIT_SYNC 0x01
|
||||
#define DB_MSG_INIT_RESP 0x02
|
||||
#define DB_MSG_SEND_DATA 0x04
|
||||
#define DB_MSG_PUSH 0x05
|
||||
#define DB_MSG_ACK_PUSH 0x06
|
||||
#define DB_MSG_SYNC_DONE 0x07
|
||||
#define DB_MSG_ERROR 0x08
|
||||
#define DB_MSG_REQUEST_SYNC 0x09
|
||||
|
||||
/* PUSH имеет фиксированный буфер 4096 байт; 4000 оставляет место заголовку и подписи. */
|
||||
#define DB_SYNC_MESSAGE_MAX 4000
|
||||
|
||||
// SEND_DATA want_from sentinel
|
||||
#define DB_WANT_FROM_NONE 0xFFFFFFFF // no request for peer's data
|
||||
|
||||
// SEND_DATA wire: [from:4][count:2][vp:4][want_from:4][records...]
|
||||
// Record: [id:8][ts:8][node_id:8][dlen:4][data][sig_len:1=64][sig:64]
|
||||
|
||||
// SYNC_DONE wire: [count:4][chain_hash8:8]
|
||||
// PUSH и записи MESSAGES: [message_id:32][ts:8BE][author:8BE][dlen:4BE][data][sig:64].
|
||||
// ACK_PUSH wire: [message_id:32]. Подтверждает конкретную запись; повторы идемпотентны.
|
||||
|
||||
// Error codes for DB_MSG_ERROR
|
||||
#define DB_ERR_NOT_FOUND 0x01 // instance not found
|
||||
#define DB_ERR_DISABLED 0x02 // instance exists but disabled
|
||||
#define DB_ERR_NOT_READY 0x03 // участники или групповая сессия ещё не готовы
|
||||
|
||||
// Defaults
|
||||
#define DB_SYNC_DEFAULT_TTL 86400
|
||||
#define DB_SYNC_DEFAULT_MAPSIZE (100UL * 1024 * 1024)
|
||||
@@ -67,6 +50,8 @@ struct DB_SYNC_INSTANCE;
|
||||
int db_sync_init(struct UTUN_INSTANCE* inst);
|
||||
// Включить ранее созданный модуль независимо от флага конфига. Повтор допустим; 0/-1.
|
||||
int db_sync_enable(struct UTUN_INSTANCE* inst);
|
||||
// Подключить MESSAGES после создания общего Merkle-движка; запланировать проверку своей истории. 0/-1.
|
||||
int db_sync_register_model(struct UTUN_INSTANCE* inst);
|
||||
// Отменить таймеры/обмен, снять обработчики; общую SQLite не закрывает.
|
||||
void db_sync_destroy(struct UTUN_INSTANCE* inst);
|
||||
|
||||
@@ -115,11 +100,14 @@ typedef void (*db_sync_insert_cb)(struct DB_SYNC_INSTANCE* si,
|
||||
uint64_t author_node_id, int initial_sync, void* arg);
|
||||
void db_sync_set_insert_cb(struct DB_SYNC_INSTANCE* si, db_sync_insert_cb cb, void* arg);
|
||||
|
||||
// Проверить цепочку: 0 — корректна, 1 — несовпадение/битые поля, -1 — операционная ошибка.
|
||||
int db_sync_chain_verify(struct DB_SYNC_INSTANCE* si);
|
||||
// Диагностика: синхронно перепроверить/очистить сохранённые записи и восстановить индекс.
|
||||
// 0 — готов, 1 — ожидается ключ автора, -1 — операционная ошибка. В обычной работе обход порционный.
|
||||
int db_sync_verify(struct DB_SYNC_INSTANCE* si);
|
||||
// Прочитать полный корень: 0 — успех, 1 — preflight ещё не завершён, -1 — ошибка. root[32] обязателен.
|
||||
int db_sync_read_root(struct DB_SYNC_INSTANCE* si, uint8_t root[32]);
|
||||
|
||||
// Peer state control (for testing — disable PUSH to isolate sync protocol)
|
||||
void db_sync_peer_set_state(struct DB_SYNC_INSTANCE* si, uint64_t node_id, uint8_t state);
|
||||
void db_sync_peer_set_paused(struct DB_SYNC_INSTANCE* si, uint64_t node_id, int paused);
|
||||
|
||||
// Per-(chat,peer) «play sound on message» flag: sound_off + sleeping peer → throttled.
|
||||
void db_sync_set_peer_sound(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t peer_node_id, int sound_on);
|
||||
@@ -131,10 +119,11 @@ void db_sync_instance_set_gated(struct DB_SYNC_INSTANCE* si, int gated);
|
||||
// Force re-initiate sync to a specific peer (for testing)
|
||||
void db_sync_reinitiate(struct DB_SYNC_INSTANCE* si, uint64_t node_id);
|
||||
|
||||
// Get last chain hash8 (for cross-peer consistency check in tests)
|
||||
int db_sync_last_chain_hash8(struct DB_SYNC_INSTANCE* si, uint64_t* out_hash8);
|
||||
// После sleep/sound переоценить работу истории; после изменения MEMBERS также повторить ожидание общих ключей.
|
||||
void db_sync_peer_policy_changed(struct UTUN_INSTANCE* inst, uint64_t peer);
|
||||
void db_sync_members_changed(struct UTUN_INSTANCE* inst, const char* ns);
|
||||
|
||||
// Sync completion callback (global, per-instance: fires when SYNC_DONE sent/received for any group)
|
||||
// Глобальная подписка на подтверждённый полный Merkle-корень истории; callback может удалить подписку/канал.
|
||||
typedef void (*db_sync_done_fn)(struct DB_SYNC_INSTANCE* si, uint64_t peer_node_id, void* arg);
|
||||
void db_sync_add_done_cbk(struct UTUN_INSTANCE* inst, db_sync_done_fn fn, void* arg);
|
||||
void db_sync_remove_done_cbk(struct UTUN_INSTANCE* inst, db_sync_done_fn fn, void* arg);
|
||||
|
||||
Reference in new issue
Block a user