diff --git a/src/dm/dm_core.c b/src/dm/dm_core.c index a6d37952..8b61cff7 100644 --- a/src/dm/dm_core.c +++ b/src/dm/dm_core.c @@ -1108,14 +1108,13 @@ void dm_invite_trampoline(void* arg) { } snprintf(conv, sizeof(conv), "%llu", (unsigned long long)dm_derive_conv_id(req->inst->node_id, req->peer_node_id)); struct dm_conv c; - if (dm_conv_load(dm, conv, &c) != 0 && dm_node_pubkeys(dm, req->peer_node_id, c.peer_x25519, c.peer_ed25519) != 0) { - DEBUG_ERROR(DEBUG_CATEGORY_DM, "invite PM: recipient keys missing peer=%llu", (unsigned long long)req->peer_node_id); - dm_invite_done(req, DM_INVITE_START_ERROR); return; - } - /* dm_start также восстанавливает маршрут через исходную группу для авто-созданной PM. */ - if (dm_start(req->inst, req->peer_node_id, c.peer_x25519, c.peer_ed25519, req->peer_name, req->source_ch_id) != 0) { - DEBUG_ERROR(DEBUG_CATEGORY_DM, "invite PM: conversation failed peer=%llu", (unsigned long long)req->peer_node_id); - dm_invite_done(req, DM_INVITE_START_ERROR); return; + if (dm_conv_load(dm, conv, &c) != 0) { + uint8_t x25519[32], ed25519[32]; + if (dm_node_pubkeys(dm, req->peer_node_id, x25519, ed25519) != 0 || + dm_start(req->inst, req->peer_node_id, x25519, ed25519, req->peer_name, req->source_ch_id) != 0) { + DEBUG_ERROR(DEBUG_CATEGORY_DM, "invite PM: conversation failed peer=%llu", (unsigned long long)req->peer_node_id); + dm_invite_done(req, DM_INVITE_START_ERROR); return; + } } DEBUG_INFO(DEBUG_CATEGORY_DM, "invite PM: building request=%llu peer=%llu source=%s ch=%s conv=%s", (unsigned long long)req->request_id, (unsigned long long)req->peer_node_id, req->source_ch_id, channel, conv); diff --git a/tests/test_dm_invite.c b/tests/test_dm_invite.c index 823d6c55..ba5114d8 100644 --- a/tests/test_dm_invite.c +++ b/tests/test_dm_invite.c @@ -155,14 +155,14 @@ int main(void) { "BEGIN SELECT RAISE(ABORT,'test invite commit failure'); END", NULL, NULL, NULL) == SQLITE_OK, "install failed commit"); request(4, target, source_id, 0); CHECK(wait_result(ua, 4, DM_INVITE_SEND_ERROR) && !message_count(), "failed commit returns error and rolls back PM"); - uint64_t route = 0; - CHECK(!scalar(nodes[0], "SELECT group_id FROM dm_conversations LIMIT 1", &route) && route == source, - "member invitation restores the existing PM's source group route"); CHECK(sqlite3_exec(nodes[0]->topo_sqlite_db, "DROP TRIGGER fail_invite", NULL, NULL, NULL) == SQLITE_OK, "remove failed commit"); request(5, target, "", 0); /* из шапки существующей PM исходная группа не передаётся */ request(4, target, "", 1); /* запоздалая отмена другой операции не отменяет текущую */ CHECK(wait_result(ua, 5, DM_INVITE_OK) && message_count() == 1, "one invitation committed for fixed peer"); + uint64_t route = 0; + CHECK(!scalar(nodes[0], "SELECT group_id FROM dm_conversations LIMIT 1", &route) && route == source, + "successful PM restores its automatically resolved shared group route"); char conv[64], messages[8192]; size_t length = 0; snprintf(conv, sizeof(conv), "%llu", (unsigned long long)dm_derive_conv_id(nodes[0]->node_id, nodes[1]->node_id)); deadline = get_time_tb() + 100000;