diff --git a/src/chat/member_sync.c b/src/chat/member_sync.c index f80469ba2..98a4e00b1 100644 --- a/src/chat/member_sync.c +++ b/src/chat/member_sync.c @@ -1778,10 +1778,7 @@ int member_sync_start(struct UTUN_INSTANCE* inst, uint64_t peer, DEBUG_WARN(DEBUG_CATEGORY_MEMBER_SYNC, "member start denied ch=%s peer=%016llx", ch_id ? ch_id : "-", (unsigned long long)peer); return -1; } - if (member_sync_verify_and_purge(inst, ch_id) < 0) { - DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: start rejected after purge failure ns=%s peer=%016llx", - MS_ID, ch_id ? ch_id : "-", (unsigned long long)peer); return -1; - } + /* Прежняя запись нужна commit_pull для проверки и fallback; start её не удаляет. */ return merkle_sync_start(inst, MT_DATA_MEMBERS, peer, ch_id, done_cb, arg); } diff --git a/src/chat/member_sync.h b/src/chat/member_sync.h index b4bc45582..c8bbfad70 100644 --- a/src/chat/member_sync.h +++ b/src/chat/member_sync.h @@ -149,9 +149,9 @@ int member_sync_subscribe_group(struct UTUN_INSTANCE* inst, struct TOPO_GROUP* g /* * Запустить синхронизацию мемберов канала ch_id с пиром peer. - * Сначала вызывает verify_and_purge, затем merkle_sync_start(MEMBERS). + * Проверяет право обмена/запроса, затем вызывает merkle_sync_start(MEMBERS). * 0 — запрос принят; <0 — не принят, done_cb не вызывается (см. merkle_sync.h). - * Ошибка очистки отклоняет запрос до merkle_sync_start, без done callback. + * Прежние записи сохраняются для проверки и fallback после получения различий. */ int member_sync_start(struct UTUN_INSTANCE* inst, uint64_t peer, const char* ch_id, merkle_sync_done_cb done_cb, void* arg); @@ -261,7 +261,7 @@ int member_sync_verify_and_purge(struct UTUN_INSTANCE* inst, const char* ch_id) * ранее завершённые каналы сохраняют результат. Не держит SQLite cursor через callbacks. */ int member_sync_verify_and_purge_all(struct UTUN_INSTANCE* inst); -/* COUNT(*) всех строк, включая placeholders/deleted; неверный аргумент/ошибка SQL дают 0. */ +/* Число опубликованных строк, включая placeholders/deleted; неверный аргумент/ошибка SQL дают 0. */ int member_sync_count(struct UTUN_INSTANCE* inst, const char* ch_id); /* diff --git a/tests/test_member_purge.c b/tests/test_member_purge.c index f7fd257f0..f7bede667 100644 --- a/tests/test_member_purge.c +++ b/tests/test_member_purge.c @@ -287,11 +287,12 @@ static void test_purge_start(struct UASYNC* ua) { struct conn_queue_entry* entry = (struct conn_queue_entry*)e->data; entry->peer_node_id = peer; entry->conn = &f.conn; assert(queue_data_put_with_index(f.inst.connections, e) == 0); int callbacks = 0; - exec_fault = "COMMIT"; + f.conn.crypto_ctx.peer_public_key[0] ^= 1; assert(member_sync_start(&f.inst, peer, "1001", purge_done, &callbacks) < 0); - reset_faults(); + f.conn.crypto_ctx.peer_public_key[0] ^= 1; assert(!f.conn.ref_count && !callbacks && member_sync_count(&f.inst, "1001") == 2); assert(member_sync_start(&f.inst, peer, "1001", purge_done, &callbacks) == 0 && f.conn.ref_count == 1); + assert(member_sync_count(&f.inst, "1001") == 2); /* Проверка прежних версий выполняется после приёма, а не при start. */ merkle_sync_cancel_peer(&f.inst, peer); assert(!f.conn.ref_count && !callbacks && !f.conn.send_input_q->waiter_head); e = queue_data_get(f.inst.connections); assert(e); queue_entry_free(e); @@ -299,7 +300,7 @@ static void test_purge_start(struct UASYNC* ua) { queue_free(f.conn.send_input_q); f.inst.topo_groups = NULL; queue_entry_free(queue_data_get(groups.group_list)); queue_free(groups.group_list); purge_destroy(&f); - DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS purge: failed start creates no request/callback; retry attaches real session; cancel releases ownership"); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS start: wrong peer key denied; accepted start preserves old versions; cancel releases ownership"); } /* Настоящие неверные подписи удаляются; короткий BLOB никогда не читается как полный ключ. */