Restore retained attachment indexes during startup and manual download

This commit is contained in:
evgeny committed 2026-10-27 02:20:02 +01:00
1 parent d9f5da130e
commit fdb11ed3ce
3 files changed
+28 -5

No files matched your search

+2 -1
View File
@@ -19,6 +19,7 @@
#include <stdint.h>
#define CC_ID "chat_core"
#define CHAT_MEDIA_BACKFILL_CHANNELS 16
/* ── Base64 encode/decode (URL-safe, used for msg "d" field prefix) ── */
@@ -100,7 +101,7 @@ struct chat_core_ctx {
int media_backfill_ran; /* was chat_msg.c g_media_startup_backfill_ran */
struct UTUN_INSTANCE* media_backfill_inst; /* was chat_msg.c g_media_startup_backfill_inst */
void* media_channel_backfill_timer; /* ограниченный batch докачки/восстановления индекса через 2с от первой заявки */
char media_channel_backfill[16][64]; /* pending ch_id */
char media_channel_backfill[CHAT_MEDIA_BACKFILL_CHANNELS][64]; /* pending ch_id */
int media_channel_backfill_pending;
void* attachment_timer;
int attachment_closing;
+25 -3
View File
@@ -752,7 +752,11 @@ static int msg_read_id(struct chat_core_ctx* cc, const char* channel, int64_t id
const void* key = sqlite3_column_blob(st, 0);
if (key) { memcpy(message_id, key, 32); result = 0; }
}
sqlite3_finalize(st);
int final_rc = sqlite3_finalize(st);
if (final_rc != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media identity finalize failed ch=%s id=%lld rc=%d", channel, (long long)id, final_rc);
result = -1;
}
if (result) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media identity missing ch=%s id=%lld rc=%d: %s",
channel, (long long)id, rc, sqlite3_errmsg(cc->db));
return result;
@@ -1227,7 +1231,7 @@ void chat_media_backfill(struct UTUN_INSTANCE* inst) {
char tbl[80]; msg_table_name(ch_id, tbl, sizeof(tbl));
char sql[256];
snprintf(sql, sizeof(sql), "SELECT data FROM \"%s\"", tbl);
snprintf(sql, sizeof(sql), "SELECT data,message_id,node_id FROM \"%s\"", tbl);
sqlite3_stmt* ms = NULL;
if (sqlite3_prepare_v2(cc->db, sql, -1, &ms, NULL) != SQLITE_OK) continue;
@@ -1260,6 +1264,22 @@ void chat_media_backfill(struct UTUN_INSTANCE* inst) {
content_type[i] = '\0';
}
int encrypted_attachment = !strcmp(content_type, ENCRYPTED_ATTACHMENT_TYPE);
uint8_t message[32];
if (encrypted_attachment) {
if (sqlite3_column_bytes(ms, 1) != 32 || !sqlite3_column_blob(ms, 1)) {
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media startup: missing encrypted message identity ch=%s", ch_id);
media_index_result_free(&result); u_free(body); continue;
}
memcpy(message, sqlite3_column_blob(ms, 1), 32);
int observed = chat_attachment_observe(inst, ch_id, message, (uint64_t)sqlite3_column_int64(ms, 2), jdata,
(size_t)sqlite3_column_bytes(ms, 0));
if (observed) {
if (observed == -1) media_queue_channel_backfill(inst, ch_id);
media_index_result_free(&result); u_free(body); continue;
}
}
char base_filename[256];
extract_base_filename(body, base_filename, sizeof(base_filename));
char final_name[256];
@@ -1277,6 +1297,8 @@ void chat_media_backfill(struct UTUN_INSTANCE* inst) {
int registered = media_index_commit(cc->db, &result, cc->my_node_id, NULL, ch_id, path, media_base);
if (!registered) total += result.num_blocks;
else DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media backfill registration failed ch=%s file=%s", ch_id, path);
if (encrypted_attachment && !registered && chat_attachment_downloaded(inst, ch_id, message))
media_queue_channel_backfill(inst, ch_id);
u_free(body);
media_index_result_free(&result);
@@ -1882,7 +1904,7 @@ static void media_channel_backfill_timer_cb(void* arg) {
struct chat_core_ctx* cc = CC(inst);
if (!cc) return;
cc->media_channel_backfill_timer = NULL;
char channels[16][64]; int count = cc->media_channel_backfill_pending;
char channels[CHAT_MEDIA_BACKFILL_CHANNELS][sizeof(cc->media_channel_backfill[0])]; int count = cc->media_channel_backfill_pending;
memcpy(channels, cc->media_channel_backfill, (size_t)count * sizeof(channels[0]));
cc->media_channel_backfill_pending = 0;
for (int i = 0; i < count; i++) chat_media_autodownload_backfill_channel(inst, channels[i]);
+1 -1
View File
@@ -848,8 +848,8 @@ int chat_service_start(struct UTUN_INSTANCE* instance) {
if (chat_attachment_init(instance) < 0) goto fail;
if (member_files_init(instance) < 0 || dm_mailbox_init(instance) < 0 || dm_core_init(instance) < 0 ||
dm_media_init(instance) < 0 || call_init(instance) < 0 || radio_call_init(instance) < 0) goto fail;
chat_media_backfill(instance);
chat_media_startup_backfill_init(instance);
chat_media_backfill(instance);
/* Все headless listeners используют IPv4:port; port=0 выбирает ОС. Ошибка отключает только этот listener. */
const struct {
const char* bind;