chat: локальное удаление канала (Android) + db_sync инстансы в куче
This commit is contained in:
1 parent
ddfffad1ed
commit
7c8d65db78
30 files changed
+466
-42
No files matched your search
@@ -351,6 +351,24 @@ static void topo_group_destroy(struct TOPO_GROUP* group) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SYS, "[GRP_DESTROY] 5 done");
|
||||
}
|
||||
|
||||
void topo_groups_remove_group(struct TOPO_GROUPS* g, uint64_t group_id) {
|
||||
if (!g || !g->group_list || group_id == TOPO_GROUP_UTUN) return;
|
||||
struct TOPO_GROUP* group = topo_groups_find(g, group_id);
|
||||
if (!group) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "remove_group: group %016llx not found", (unsigned long long)group_id); return; }
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "remove_group: id=%016llx type=%d ch=%s",
|
||||
(unsigned long long)group_id, group->group_type, group->channel_id);
|
||||
|
||||
/* освободить подписчиков BGP-событий (member_sync и др.), т.к. группа умирает */
|
||||
struct topo_node_cbk_entry* c = group->node_cbks;
|
||||
while (c) { struct topo_node_cbk_entry* n = c->next; u_free(c); c = n; }
|
||||
group->node_cbks = NULL;
|
||||
|
||||
queue_remove_data(g->group_list, &group->ll);
|
||||
topo_group_destroy(group);
|
||||
queue_entry_free(&group->ll);
|
||||
}
|
||||
|
||||
struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) {
|
||||
if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "instance is NULL"); return NULL; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node_id=%016llx", (unsigned long long)instance->node_id);
|
||||
|
||||
@@ -253,6 +253,15 @@ struct TOPO_GROUP* topo_groups_find(struct TOPO_GROUPS* g, uint64_t group_id);
|
||||
*/
|
||||
struct TOPO_GROUP* topo_groups_create_group(struct TOPO_GROUPS* g, uint64_t group_id, uint8_t group_type, const char* channel_id);
|
||||
|
||||
/**
|
||||
* @brief Удаляет одну группу по id (разрушает conn_mgr, connect-цикл, broadcast,
|
||||
* recovery, узлы и подписчиков node_cbks) и извлекает её из group_list.
|
||||
*
|
||||
* Используется при локальном удалении чат-канала. Группу по умолчанию
|
||||
* (TOPO_GROUP_UTUN) удалять нельзя — функция это игнорирует.
|
||||
*/
|
||||
void topo_groups_remove_group(struct TOPO_GROUPS* g, uint64_t group_id);
|
||||
|
||||
/**
|
||||
* @brief Добавляет conn в senders_list (если нет), отправляет запрос таблицы (nodeinfo).
|
||||
*
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../transport_layer/node_conn_direct.h"
|
||||
#include "ntp_time.h"
|
||||
#include "../chat/chat_core.h"
|
||||
#include "../chat/chat_event.h"
|
||||
|
||||
#define TGI_ID "topo_group_invite"
|
||||
#define TGI_TIMEOUT_MS 2000
|
||||
@@ -311,6 +312,10 @@ static void tgi_handle_info_resp(struct ETCP_CONN* conn, const uint8_t* data, si
|
||||
}
|
||||
chat_core_ensure_channel_ready(ch_id);
|
||||
|
||||
{ uint8_t evt[65]; uint8_t ch_id_len = (uint8_t)strlen(ch_id);
|
||||
evt[0] = ch_id_len; memcpy(evt + 1, ch_id, ch_id_len);
|
||||
chat_event_post(CHAT_EVT_CHANNEL_UPDATED, evt, 1 + ch_id_len); }
|
||||
|
||||
/* ── верифицируем update_sig приглашающего ── */
|
||||
{
|
||||
const uint8_t* inv_ed = conn->peer_ed25519_pubkey;
|
||||
|
||||
@@ -415,6 +415,42 @@ int topo_node_sqlite_channel_put(sqlite3* db, const char* channel_id,
|
||||
return rc == SQLITE_DONE ? 0 : -1;
|
||||
}
|
||||
|
||||
int topo_node_sqlite_channel_delete(sqlite3* db, const char* channel_id) {
|
||||
if (!db || !channel_id || !channel_id[0]) return -1;
|
||||
|
||||
char peers_tbl[80]; peers_table_name(channel_id, peers_tbl, sizeof(peers_tbl));
|
||||
char msg_tbl[80]; sanitize_ch_id(channel_id, msg_tbl, sizeof(msg_tbl));
|
||||
/* msg_<san> */
|
||||
char msg_full[80]; snprintf(msg_full, sizeof(msg_full), "msg_%s", msg_tbl);
|
||||
|
||||
/* 1. drop per-channel tables (индексы дропятся вместе с таблицей) */
|
||||
char sql[128];
|
||||
snprintf(sql, sizeof(sql), "DROP TABLE IF EXISTS \"%s\"", peers_tbl);
|
||||
sqlite3_exec(db, sql, NULL, NULL, NULL);
|
||||
snprintf(sql, sizeof(sql), "DROP TABLE IF EXISTS \"%s\"", msg_full);
|
||||
sqlite3_exec(db, sql, NULL, NULL, NULL);
|
||||
|
||||
/* 2. delete channels row (вместе с канальными privkey) */
|
||||
sqlite3_stmt* st = NULL;
|
||||
if (sqlite3_prepare_v2(db, "DELETE FROM channels WHERE channel_id=?", -1, &st, NULL) == SQLITE_OK) {
|
||||
sqlite3_bind_text(st, 1, channel_id, -1, SQLITE_STATIC);
|
||||
sqlite3_step(st);
|
||||
sqlite3_finalize(st);
|
||||
}
|
||||
|
||||
/* 3. delete merkle tree hashes for this namespace */
|
||||
sqlite3_stmt* mh = NULL;
|
||||
if (sqlite3_prepare_v2(db, "DELETE FROM merkle_tree_hash WHERE namespace=?", -1, &mh, NULL) == SQLITE_OK) {
|
||||
sqlite3_bind_text(mh, 1, channel_id, -1, SQLITE_STATIC);
|
||||
sqlite3_step(mh);
|
||||
sqlite3_finalize(mh);
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_node_sqlite_channel_delete: ch=%s peers=%s msg=%s",
|
||||
channel_id, peers_tbl, msg_full);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Упрощённый плейсхолдер мембера от topo_group: только node_id + pubkeys, source=1.
|
||||
* Не участвует в merkle-хеше. Если запись уже есть (полная merkle) — не трогает её.
|
||||
* Позже полная merkle-запись дополняет/перезаписывает блоки и сбрасывает source=0. */
|
||||
|
||||
@@ -33,6 +33,10 @@ int topo_node_sqlite_channel_put(sqlite3* db, const char* channel_id,
|
||||
const uint8_t* ed25519_pub, const uint8_t* ed25519_priv,
|
||||
const uint8_t* signature);
|
||||
|
||||
/* Полное локальное удаление канала: DROP peers_<id>/msg_<id>, DELETE channels,
|
||||
* DELETE merkle_tree_hash WHERE namespace=<channel_id>. 0=ок. */
|
||||
int topo_node_sqlite_channel_delete(sqlite3* db, const char* channel_id);
|
||||
|
||||
/* Упрощённый плейсхолдер мембера от topo_group (source=1, не участвует в merkle-хеше). */
|
||||
int topo_node_sqlite_member_placeholder_put(sqlite3* db, const char* channel_id, uint64_t node_id,
|
||||
const uint8_t* x25519_pubkey, const uint8_t* ed25519_pubkey);
|
||||
|
||||
Reference in new issue
Block a user