From 4188afb3c552379a8397af20800c8f29ab51649a Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 18 Jul 2026 16:08:47 +0300 Subject: [PATCH] db_sync: lazy-register channel instance on INIT_SYNC when not pre-registered When INIT_SYNC arrives for an unknown hash, scan all msg_* tables in sqlite_master, compute SHA256 of channel_id, match the hash, and auto-register via db_sync_instance_add. Fixes invite flow where channel was created but db_sync wasn't notified. --- src/db_sync.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/db_sync.c b/src/db_sync.c index 236dce04..47e98eb2 100644 --- a/src/db_sync.c +++ b/src/db_sync.c @@ -1059,13 +1059,34 @@ static void db_sync_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) struct DB_SYNC_INSTANCE* si = db_instance_find(db, hash); if (!si) { - DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, - "recv msg type=0x%02x from %016llx hash=%016llx — instance NOT FOUND; sending DB_ERR_NOT_FOUND", - type, (unsigned long long)src, (unsigned long long)hash); - DEBUG_TRACE(DEBUG_CATEGORY_DB_SYNC, "→ instance not found for hash=%016llx", (unsigned long long)hash); - uint8_t err[2]; err[0] = DB_MSG_ERROR; err[1] = DB_ERR_NOT_FOUND; - db_sync_send_hash(db, src, hash, err, 2); - queue_dgram_free(entry); queue_entry_free(entry); return; + /* lazy-register: find table msg_ with matching SHA256 */ + sqlite3_stmt* st = NULL; + if (sqlite3_prepare_v2(db->db, + "SELECT name, substr(name,5) FROM sqlite_master WHERE type='table' AND name LIKE 'msg_%'", + -1, &st, NULL) == SQLITE_OK) { + while (sqlite3_step(st) == SQLITE_ROW) { + const char* tbl = (const char*)sqlite3_column_text(st, 0); + const char* ch_id = (const char*)sqlite3_column_text(st, 1); + if (!ch_id || !ch_id[0]) continue; + uint64_t h; { uint8_t sh[32]; SC_SHA256_CTX ctx; sc_sha256_init(&ctx); sc_sha256_update(&ctx, (const uint8_t*)ch_id, strlen(ch_id)); sc_sha256_final(&ctx, sh); memcpy(&h, sh, 8); } + if (h == hash) { + si = db_sync_instance_add(db->inst, tbl, hash); + if (si) { si_peer_add(si, src); } + DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "lazy-register: tbl=%s ch=%s hash=%016llx", tbl, ch_id, (unsigned long long)hash); + break; + } + } + sqlite3_finalize(st); + } + if (!si) { + DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, + "recv msg type=0x%02x from %016llx hash=%016llx — instance NOT FOUND; sending DB_ERR_NOT_FOUND", + type, (unsigned long long)src, (unsigned long long)hash); + DEBUG_TRACE(DEBUG_CATEGORY_DB_SYNC, "→ instance not found for hash=%016llx", (unsigned long long)hash); + uint8_t err[2]; err[0] = DB_MSG_ERROR; err[1] = DB_ERR_NOT_FOUND; + db_sync_send_hash(db, src, hash, err, 2); + queue_dgram_free(entry); queue_entry_free(entry); return; + } } if (!si->enabled) { uint8_t err[2]; err[0] = DB_MSG_ERROR; err[1] = DB_ERR_DISABLED;